https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87390
Bug ID: 87390 Summary: GCC does not honor FLT_EVAL_METHOD on implicit conversion of integer to floating point Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: vincent-gcc at vinc17 dot net Target Milestone: --- On 32-bit x86, i.e. with FLT_EVAL_METHOD = 2, the following program #include <stdio.h> #include <float.h> int main (void) { unsigned long long i = 1ULL << 63; double d; d = i; printf ("FLT_EVAL_METHOD = %d\n", (int) FLT_EVAL_METHOD); printf ("%d\n", d + 1.0 == (float) d + (float) 1.0); printf ("%d\n", d == (float) d + (float) 1.0); printf ("%d\n", d == i + 1); return 0; } gives: cventin:~> gcc-snapshot -std=c99 tst.c -o tst -m32 cventin:~> ./tst FLT_EVAL_METHOD = 2 1 0 1 instead of 0 for the last line. Indeed, according to ISO C99 5.2.4.2.2: Except for assignment and cast (which remove all extra range and precision), the values of operations with floating operands and values subject to the usual arithmetic conversions and of floating constants are evaluated to a format whose range and precision may be greater than required by the type. The use of evaluation formats is characterized by the implementation-defined value of FLT_EVAL_METHOD: [...] 2 evaluate all operations and constants to the range and precision of the long double type. (slightly changed in C11: "[...] the values yielded by operators with [...]"). For the first two tests, (float) d + (float) 1.0 has type float and has been evaluated with the type long double, and for the == test, this expression is converted to the semantic type double (because the left-hand side has type double), but the evaluation type is long double, thus the results 1 and 0 respectively. For the third test, i + 1 has type unsigned long long, and for the == test, similarly, this expression should be converted to the semantic type double, but the evaluation type should be long double, thus the result should be 0, like in the second test, not 1.