Repository navigation
fix: detect NaN and infinity from the bits of the double - #207
Merged
Merged
Conversation
ImNan called the unqualified isnan, which fails to build when <cmath> is included before ImPlot3D and the C library's <math.h> is found ahead of the C++ one (a sysroot or system include directory passed with -I): isnan is then neither a macro nor a global function. Switching to std::isnan only moves the failure to other setups, such as libc++ without <cmath>. ImNan and ImNanOrInf now copy the double into an ImU64 and test the IEEE-754 exponent and mantissa, so they need no math header, and unlike isnan or val != val they keep detecting NaN under -ffast-math and /fp:fast, where the compiler may delete floating-point NaN checks. Under -ffinite-math-only an empty asm statement hides the bits from the optimizer, since clang otherwise folds the exponent test to false. Mirrors the same fix in ImPlot (epezent/implot#565).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ImNan()calls the unqualifiedisnan, which only compiles if the right math header wins. When<cmath>is included before ImPlot3D and the C library's<math.h>is found ahead of the C++ one,isnanis not declared at all. That happens, for example, when a sysroot include directory is passed with-I.std::isnandoesn't fix it either: it breaks in other setups, such as libc++ without<cmath>. There is also a runtime problem. With-ffast-math, the compiler may assume NaN never exists and delete the check, so NaN points get drawn instead of skipped.ImNan()andImNanOrInf()now read the bits of the double and check the IEEE-754 pattern directly. NaN means all exponent bits are set and the mantissa is nonzero, and infinity or NaN means all exponent bits are set. This needs no math header, and it keeps working under-ffast-mathand/fp:fast. In finite-math builds, an emptyasmstatement keeps clang from folding the test away. Mirrors the same fix in ImPlot (epezent/implot#565).