For hosted C implementations, one can do a #include <math.h>
and use the NAN
macro if defined. For instance, with GCC, it is implemented by a builtin: (__builtin_nanf (""))
.
For freestanding C implementations (on which the <math.h>
header may not be available) or when the NAN
macro is not defined (which might happen even though NaN's may be supported), one can generate a NaN with a floating-point operation such as 0.0 / 0.0
. However, there may be several issues with it.
First, such an operation also generates an exception, with a possible trap on some C implementations. One can make sure that it is computed at compile time with:
static double my_nan = 0.0 / 0.0;
Another issue is that Microsoft Visual C++ (at least some versions) attempts to evaluate 0.0 / 0.0
at compile time (even when this expression is in an arbitrary place in the code) and complains about its validity. So, the solution here is the opposite one: make sure that the compiler will not evaluate it at compile time, by doing:
static double zero = 0.0;
and then use zero / zero
. Since these solutions are conflicting, one can test the compiler with preprocessor directives (#if
...) on specific macros.
One may also choose a solution based on the NaN encoding, but there are also portability issues. First, the IEEE 754 standard does not completely define the encoding of a NaN, in particular the way to distinguish quiet and signaling NaNs (and hardware differs in practice); signaling NaNs will yield undefined behavior. Moreover, the IEEE 754 standard does not define how the bit string is represented in memory, i.e. the endianness may need to be detected. If these problems are solved, a union or an array of unsigned char
with a pointer cast is fine to get the floating-point type. Do not use an integer with a pointer cast on its address to do type punning as this will break the C aliasing rules.