https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93806
--- Comment #34 from Alexander Cherepanov <ch3root at openwall dot com> --- (In reply to Vincent Lefèvre from comment #13) > > Since C without Annex F allows arbitrarily awful floating point results, > > In C without Annex F, division by 0 is undefined behavior (really undefined > behavior, not an unspecified result, which would be very different). > > With the examples using divisions by 0, you need to assume that Annex F > applies, but at the same time, with your interpretation, -fno-signed-zeros > breaks Annex F in some cases, e.g. if you have floating-point divisions by > 0. So I don't follow you... You seem to say that either Annex F is fully there or not at all but why? -fno-signed-zeros breaks Annex F but only parts of it. Isn't it possible to retain the other parts of it? Maybe it's impossible or maybe it's impossible to retain division by zero, I don't know. What is your logic here? (In reply to Vincent Lefèvre from comment #15) > Note that there are very few ways to be able to distinguish the sign of > zero. The main one is division by zero. Other ones are: > > * Conversion to a character string, e.g. via printf(). But in this case, if > -fno-signed-zeros is used, whether "0" or "-0" is output (even in a way that > seems to be inconsistent) doesn't matter since the user does not care about > the sign of 0, i.e. "0" and "-0" are regarded as equivalent (IIRC, this > would be a bit like NaN, which has a sign bit in IEEE 754, but the output > does not need to match its sign bit). This means that you cannot implement you own printf: if you analyze sign bit of your value to decide whether you need to print '-', the sign of zero is significant in your code. IOW why do you think that printf is fine while "1 / x == 1 / 0." is not? > * Memory analysis. Again, the sign does not matter, but for instance, > reading an object twice as a byte sequence while the object has not been > changed by the code must give the same result. I doubt that this is affected > by optimization. Working with objects on byte level is often optimized too: ---------------------------------------------------------------------- #include <string.h> #include <stdio.h> __attribute__((noipa)) // imagine it in a separate TU static double opaque(double d) { return d; } int main() { int zero = opaque(0); double x = opaque(-0.); long l; memcpy(&l, &x, sizeof l); int a = l == 0; // or just this: //int a = (union { double d; long l; }){x}.l == 0; printf("zero = %d\n", zero); opaque(a); if (zero == a) { opaque(0); if (x == 0) { opaque(0); if (a) { opaque(0); if (zero == 1) printf("zero = %d\n", zero); } } } } ---------------------------------------------------------------------- $ gcc -std=c11 -pedantic -Wall -Wextra -fno-signed-zeros -O3 test.c && ./a.out zero = 0 zero = 1 ---------------------------------------------------------------------- gcc x86-64 version: gcc (GCC) 10.0.1 20200303 (experimental) ---------------------------------------------------------------------- Bonus: bare -fno-signed-zeros is used here, without -fno-trapping-math.