3

Is there a way to simulate nan/inf in a constant expression and without! using the C macros HUGE_VAL and INFINITY or any other for that matter! Plus, even with them, it still isn't constexpr.

I do not wish to use any standard function that the C++ standard library or the C standard library provides.

Of course the following doesn't compile. Compiler says constexpr variable must be initialized with a constant expression...

template<typename T = double>
constexpr T NaN = T(0.0 / 0.0);

Method that the MSVC compiler uses also doesn't compile:

template<typename T = double>
constexpr T NaN = T(1e+300); //with some changes, apparently having the float overflow

I know this is kind of broad, but this is for a library and I'm looking for some educated advice! Thanks!

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
DeiDei
  • 10,205
  • 6
  • 55
  • 80
  • 3
    http://en.cppreference.com/w/cpp/types/numeric_limits – Mat Dec 31 '15 at 17:19
  • @Mat I shall add more detail to the question. I wish not to use any of the functions that the STL or the C standard library provide. – DeiDei Dec 31 '15 at 17:20
  • The C and C++ standards do not specifiy a particular way that these values can be constructed as constants. For example `clang` has a `__builtin_nan` (or something very similar), which is translated at code generation time to make the "not a number" constant. – Mats Petersson Dec 31 '15 at 17:24
  • @LightnessRacesinOrbit What's wrong with knowing how to do it yourself? That's why I ask. – DeiDei Dec 31 '15 at 17:31
  • 2
    @DeiDei if you wish to know how to do it yourself, then see how libraries implement it. The standard library is open source. – bolov Dec 31 '15 at 17:32
  • 4
    This requires compiler magic. – T.C. Dec 31 '15 at 17:33
  • 1
    "knowing how to do this" involves knowing WHAT the compiler does. And most of the time, you can't really know that - for open source compilers, it's possible to figure out, but it may not be trivial, since there are typically several layers of "magic" involved. – Mats Petersson Dec 31 '15 at 17:37
  • There is no standard way "how to do it yourself" that conforms to the standard. The way that conforms to the standard is using `std::numeric_limits::infinity()`, which you dismissed in your first comment. The implementation of `std::numeric_limits::infinity()` is likely to used reserved identifiers or contain expressions that are not defined by the standard and differ greatly between compilers. If you want to put it into a portable library, there is no way around `std::numeric_limits`. – Michael Karcher Dec 31 '15 at 17:54
  • 2
    Fwiw: https://github.com/llvm-mirror/libcxx/blob/master/include/limits#L375-L376 – Howard Hinnant Dec 31 '15 at 18:47
  • @HowardHinnant so, in other words, compiler magic :) – T.C. Dec 31 '15 at 19:42
  • why not STL? It's the standard library in C++ and should work across all compilers, unlike intrinsics – phuclv Oct 26 '22 at 07:21

1 Answers1

0
__builtin_nan("0")

I checked this using compiler explorer and it seems to be supported in gcc 6.1+, clang 6.0.0+, MSVC v19.24+ and many other uncommon compilers as well.

Use what the compiler provides. This is the only non-standard way. Check if and how your compiler provides this feature. Also keep in mind the standard library provides std::numeric_limits<T>::has_quiet_NaN for a reason.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 29 '22 at 17:07