`fmt::isnan` triggers floating-point exception for NaN values
Closed this issue · 4 comments
Note: floating-point exceptions are not the same as C++ exceptions! See: https://www.gnu.org/savannah-checkouts/gnu/libc/manual/html_node/Control-Functions.html
Commit ef54f9a changed the implementation of fmt::isnan
from:
template <typename T> constexpr bool isnan(T value) {
return value != value; // std::isnan doesn't support __float128.
}
To:
template <typename T> constexpr bool isnan(T value) {
return !(value >= value); // std::isnan doesn't support __float128.
}
The commit description says that this was done to suppress -Wfloat-equal
warnings. The problem is that these two implementations are subtly different: while they both return the same value, the newer implementation also sets a floating-point exception flag. The reason is that while for IEEE-754 floating-point numbers the operation NaN != NaN
is well defined and will always return true, NaN >= NaN
is technically an invalid operation, hence why the exception flag is set (at least this is my non-expert understanding).
This has been causing headaches for a project I'm working on because I wanted to trace where floating-point exceptions were emanating from in my program (using the GNU-specific feenableexcept
function), but fmt::isnan
will raise a spurious exception every time a NaN is passed in. Changing the code to use value != value
instead fixes things.
I guess there are different ways to fix this, but maybe you could just return to using value != value
and find another way to suppress the warning (e.g. with a comment or a compiler argument)?
Thanks for reporting. Could you by any chance provide a godbolt repro that demonstrates the issue?
Sure. Here you go: https://godbolt.org/z/Pvc43M46n
I think reverting to != makes sense. Could you submit a PR to do this and add a new test case that checks FP exceptions?
Sure!