GCC doesn't seem to comply with IEEE-754 Section 7.2 on INVALID operation. The section 7.2 according to IEEE-754, found in: (https://www.gnu.org/software/libc/manual/html_node/FP-Exceptions.html) (https://www-users.cse.umn.edu/~vinals/tspot_files/phys4041/2020/IEEE%20Standard%20754-2019.pdf) The exceptions defined in IEEE 754 are: ‘Invalid Operation’ This exception is raised if the given operands are invalid for the operation to be performed. Examples are (see IEEE 754, section 7): 1-Addition or subtraction: ∞ - ∞. (But ∞ + ∞ = ∞). 2-Multiplication: 0 · ∞. 3-Division: 0/0 or ∞/∞. 4-Remainder: x REM y, where y is zero or x is infinite. 5-Square root if the operand is less than zero. More generally, any mathematical function evaluated outside its domain produces this exception. 6-Conversion of a floating-point number to an integer or decimal string, when the number cannot be represented in the target format (due to overflow, infinity, or NaN). 7-Conversion of an unrecognizable input string. 8-Comparison via predicates involving < or >, when one or other of the operands is NaN. You can prevent this exception by using the unordered comparison functions instead. It seems that GCC 14.1.0 deosn't raise the FE_INVALID on points 6 and 8, with the following results: (pinf >= qnan): 0 No Exception reported (zero <= snan): 0 No Exception reported static_cast<std::int32_t>(some_finite_large_double): 2147483647 No Exception reported for the program ``` const auto pinf = std::numeric_limits<double>::infinity(); const auto ninf = std::copysign(pinf, -1.0); const auto qnan = std::numeric_limits<double>::quiet_NaN(); const auto snan = std::numeric_limits<double>::signaling_NaN(); constexpr auto some_finite_large_double{ 598008216632976371697735644702348584536405246902083247220875921706093794716375762404103004004990504111786204800430166155026589905240121409306972824498630058082565445957748647537262486126146850127872.0}; const double zero{0.0}; // see point 8 { volatile auto result = (pinf >= qnan); fe_status = check_fe(); std::cout << "\n"; std::cout << "(pinf >= qnan): " << result << "\n"; std::cout << fe_status << "\n"; } // see point 8 { volatile auto result = (zero <= snan); fe_status = check_fe(); std::cout << "\n"; std::cout << "(zero <= snan): " << result << "\n"; std::cout << fe_status << "\n"; } // see point 6 { volatile auto result = static_cast<std::int32_t>(some_finite_large_double); fe_status = check_fe(); std::cout << "\n"; std::cout << "static_cast<std::int32_t>(double): " << result << "\n"; std::cout << fe_status << "\n"; } ``` gcc command: `g++-14 -o test -std=c++17 fe_invalid.cpp -O2 -frounding-math -fsignaling-nans -ftrapping-math -fno-builtin -fno-strict-aliasing -fwrapv` So, for comaparison of NaNs and quantization for finite large numbers, e.g. casting to smaller int32_t. The gcc is not reporting/triggering FE_INVALID While with clang using `-ffp-exception-behavior=strict`, all of the them report FE_INVALID as expected. ``` clang++-19 -o test -std=c++20 fe_invalid.cpp -O2 -ffp-exception-behavior=strict && ./test ... (pinf >= qnan): 0 FE_INVALID (zero <= snan): 0 FE_INVALID static_cast<std::int32_t>(double): -2147483648 FE_INVALID ``` Using clang command: `clang++-19 -o test -std=c++20 fe_invalid.cpp -O2 -ffp-exception-behavior=strict` The results are consistent between x86-64, armv8.1-a and armv9.2-a
>for the program This is only a snip of code and not a full program.
Full comparison between gcc and clang along with issue reproduction can be found here: https://www.godbolt.org/z/c1foMGjbo
The C and C++ standards only madate this part of IEEE-754 when #pragma FENV_ACCESS on, which is not implemented by GCC yet. *** This bug has been marked as a duplicate of bug 34678 ***