Why does GCC implement isnan() more efficiently for C++ <cmath> than C <math.h>?
Looking at <cmath>
for libstdc++ shipped with gcc 4.9 you get this:
constexpr bool isnan(double __x) { return __builtin_isnan(__x); }
A constexpr
function could be aggressively inlined and, of course, the function just delegates the work over to __builtin_isnan
.
The <math.h>
header doesn't use __builtin_isnan
, rather it uses an __isnan
implementation which is kind of long to paste here but it's lines 430 of math.h
on my machineā¢. Since the C99 standard requires using a macro for isnan
et al (section 7.12 of the C99 standard) the 'function' is defined as follows:
#define isnan(x) (sizeof (x) == sizeof (float) ? __isnanf (x) \ : sizeof (x) == sizeof (double) ? __isnan (x) \ : __isnanl (x))
However, I see no reason why it can't use __builtin_isnan
instead of __isnan
so I suspect it's an oversight. As Marc Glisse points out in the comments, there is a relevant bug report for a similar issue using isinf
instead of isnan
.