I think it should be fairly simple to amend the perl source so that this warning is eliminated
For anyone interested, here's the patch to sv.c that fixes the problem in a way that doesn't produce any warnings:
Update: The patch meets the objective, but there's still scope for improvement:
1) "
précis + 7" is overkill. All that's needed to avoid the compilation warning is "
précis + 1";
2) the condition "
&& float_need < sizeof(ebuf)" is not needed as it's implied by the next condition;
3) the variable
float_need is always set at 35 which feels wrong. AFAICS, "
sizeof(ebuf) - float_need" always evaluates to 92 (ie 127 - 35).
--- /cygdrive/c/comp/perl-5.33.2/sv.c 2020-10-04 18:15:27.028350200
++1100
+++ sv.c 2020-10-04 18:13:55.508841200 +1100
@@ -13109,13 +13109,17 @@
/* check, in manner not involving wrapping, that it w
+ill
* fit in ebuf */
&& float_need < sizeof(ebuf)
- && sizeof(ebuf) - float_need > precis
+ && sizeof(ebuf) - float_need > precis + 7
&& !(width || left || plus || alt)
&& !fill
&& intsize != 'q'
) {
WITH_LC_NUMERIC_SET_TO_NEEDED_IN(in_lc_numeric,
- SNPRINTF_G(fv, ebuf, sizeof(ebuf), precis)
+#if defined(USE_LONG_DOUBLE)
+ PERL_UNUSED_RESULT(sprintf(ebuf, "%.*Lg", (int)pr
+ecis, (NV) fv))
+#else
+ PERL_UNUSED_RESULT(sprintf(ebuf, "%.*g", (int)pr
+ecis, (NV) fv))
+#endif
);
elen = strlen(ebuf);
eptr = ebuf;
AFAICT changing
précis to
précis + 7 does not change functionality, and it's enough to eradicate the warning that the other changes would otherwise introduce
Here's the patch to t/op/sprintf2.t that would have detected the original issue:
--- sprintf2.t_orig 2020-10-04 18:24:56 +1100
+++ sprintf2.t 2020-10-04 18:24:37 +1100
@@ -1178,4 +1178,25 @@
is($off2, 1, "offset after 0");
}
+# %g formatting was broken on Ubuntu, Debian and perhaps other system
+s
+# for a long time. Here we verify that no such breakage still exists.
+
+if($Config{nvsize} == 8) {
+ cmp_ok(sprintf("%.54g", 0.3), 'eq', '0.29999999999999998889776975
+3748434595
763683319091796875',
+ "sprintf( \"%.54g\", 0.3 ) renders correctly");
+}
+elsif($Config{nvtype} eq 'long double' && ($Config{longdblkind} == 3
+|| $Config
{longdblkind} == 4)) {
+ cmp_ok(sprintf("%.64g", 0.3), 'eq', '0.30000000000000000001084202
+1724855044
3400745280086994171142578125',
+ "sprintf( \"%.64g\", 0.3 ) renders correctly");
+}
+elsif($Config{nvtype} eq 'long double' && $Config{longdblkind} >= 5 &
+& $Config{
longdblkind} <= 8) {
+ # oops ... TODO (for double-double)
+else {
+ cmp_ok(sprintf("%.115g", 0.3), 'eq',
+ '0.2999999999999999999999999999999999903703502780638207347
+2011028707
5363407309491758923059023800306022167205810546875',
+ "sprintf( \"%.115g\", 0.3 ) renders correctly");
+}
+
+
done_testing();
Update:I probably should point out that the "original issue" afflicts only perls whose nvsize is 8, AFAICT.
Therefore, those tests that I've added to sprintf2.t for other types of NV are, in fact,, unrelated to that "original issue".
Cheers,
Rob