Bug 20759 – Invalid printf checks for long double on win64

Status
NEW
Severity
minor
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Windows
Creation time
2020-04-22T12:23:28Z
Last change time
2024-12-13T19:08:15Z
Assigned to
No Owner
Creator
moonlightsentinel
Moved to GitHub: dmd#17952 →

Comments

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
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17952 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB