Comment #0 by moonlightsentinel — 2020-04-22T12:23:28Z
DMDs printf check does not handle C's long double properly on Win64 (which is equivalent to D's double according to e.g. https://docs.microsoft.com/en-us/cpp/cpp/fundamental-types-cpp?view=vs-2015)
===========================================
import core.stdc.config : c_long_double;
import core.stdc.stdio : printf;
void main()
{
// c_long_double is double on win64
printf("%Lg", c_long_double.init); // Invalid deprecation
printf("%Lg", real.init); // Silently accepted
}
===========================================
dmd -m64 printf.d
printf.d(7): Deprecation: argument nan for format specification "%Lg" must be real, not double
Comment #1 by kinke — 2020-04-22T14:26:09Z
This is specific to DMD and should be an issue with -m32mscoff too. As you said, the MSVC `long double` type is a (for C++, differently mangled than double) 64-bit double (IIRC, Microsoft outright forbids X87 usage in kernel code), while DMD goes with 80-bit X87 reals for those targets (so printf and scanf etc. from the MS runtime cannot be used without converting to lower precision first). LDC uses 64-bit reals for MSVC targets, so this works.
The deprecation wrt. double is IMO valid, as `%Lg` with a double isn't portable and just happens to work for targets with 64-bit reals, but this deprecation should IMO be host-agnostic, i.e., not suddenly popping up when targeting AArch64 or Posix x86.
Comment #2 by moonlightsentinel — 2020-04-22T14:52:07Z
(In reply to kinke from comment #1)
> This is specific to DMD and should be an issue with -m32mscoff too.
-m32mscoff yiels the same deprecation message
> The deprecation wrt. double is IMO valid, as `%Lg` with a double isn't
> portable and just happens to work for targets with 64-bit reals, but this
> deprecation should IMO be host-agnostic, i.e., not suddenly popping up when
> targeting AArch64 or Posix x86.
Sure but it's still a false positive on certain targets. Also, this snippet would still cause deprecations despite working for 64 and 80 bit reals:
printf("%Lg", cast(c_long_double) value);
Should a user have to replace this with e.g.:
static if (is(c_long_double == double))
enum fmt = "%g";
else
enum fmt = "%Lg";
printf(fmt, value);
Comment #3 by kinke — 2020-04-22T15:24:52Z
(In reply to moonlightsentinel from comment #2)
> Should a user have to replace this with e.g.:
Of course not, that's why LDC diverges. ;) The proper long-term solution is IMO redefining D `real` as corresponding to C `long double`, not the 'largest FP size implemented in hardware'.
Comment #4 by moonlightsentinel — 2020-04-22T16:22:58Z
Oky, i misunderstood your first post in that regard.
Seems like a reasonable long term solution but it might be useful to recognize & handle 64 bit reals until then.
Comment #5 by dkorpel — 2021-02-27T16:03:03Z
*** Issue 21666 has been marked as a duplicate of this issue. ***
Comment #6 by robert.schadek — 2024-12-13T19:08:15Z