note
syphilis
<I>I think it should be fairly simple to amend the perl source so that this warning is eliminated</I><br><br>
For anyone interested, here's the patch to sv.c that fixes the problem in a way that doesn't produce any warnings:
<br><br><b>Update:</b> The patch meets the objective, but there's still scope for improvement:
<br> 1) "<c>précis + 7</c>" is overkill. All that's needed to avoid the compilation warning is "<c>précis + 1</c>";
<br> 2) the condition "<c>&& float_need < sizeof(ebuf)</c>" is not needed as it's implied by the next condition;
<br> 3) the variable <c>float_need</c> is always set at 35 which feels wrong. AFAICS, "<c>sizeof(ebuf) - float_need</c>" always evaluates to 92 (ie 127 - 35).
<br><br>
<c>
--- /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 will
* 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)precis, (NV) fv))
+#else
+ PERL_UNUSED_RESULT(sprintf(ebuf, "%.*g", (int)precis, (NV) fv))
+#endif
);
elen = strlen(ebuf);
eptr = ebuf;
</c>
AFAICT changing <c>précis </c> to <c>précis + 7</c> does not change functionality, and it's enough to eradicate the warning that the other changes would otherwise introduce
<br>Here's the patch to t/op/sprintf2.t that would have detected the original issue:
<c>
--- 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 systems
+# 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.299999999999999988897769753748434595
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.300000000000000000010842021724855044
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.29999999999999999999999999999999999037035027806382073472011028707
5363407309491758923059023800306022167205810546875',
+ "sprintf( \"%.115g\", 0.3 ) renders correctly");
+}
+
+
done_testing();
</c>
<b>Update:</b>I probably should point out that the "original issue" afflicts only perls whose nvsize is 8, AFAICT.
<br> Therefore, those tests that I've added to sprintf2.t for other types of NV are, in fact,, unrelated to that "original issue".
<br><br>Cheers,<br>Rob
11122363
11122528