std::numeric_limits::quiet_NaN() vs. std::nan() vs. NAN

Mikhail picture Mikhail · Feb 4, 2017 · Viewed 6.9k times · Source

I was surprised by the number of C++ facilities to represent quiet NaN value. I found three standard ways:

  1. std::numeric_limits<T>::quiet_NaN() - generic, and I thought it was the chosen one
  2. std::nan, std::nanf, std::nanl - family of functions accepting const char* argument
  3. NAN - a macro, "which evaluates to a quiet not-a-number"

Each of these were introduced in C++11. I have several questions regarding this:

  1. What does const char* argument stand for in std::nan and co? How it is used?
  2. Why the hell we need to add a macro in C++11, while we already added a generic trait class for this purpose? (Is it for compatibility with C?)
  3. What is the one I should use by default? (I suppose this is first)

Answer

einpoklum picture einpoklum · Feb 4, 2017

std::nan, std::nanl and std::nanf are inherited from the C Math library; so is the NAN macro. They all live in C's <math.h>. As @NicolBolas suggests, however, they were only introduced in C++11 because they were not part of ANSI C, but rather of C99, a newer version of the C language standard. The C++ standards committee was making an effort to 'update' the C compatibility, so to speak.

std::numeric_limits<T> was designed for C++ itself (well before C++11), and that's what I'd use.

So, the bottom line answer is: C99 compatibility.