¿Por qué GCC implementa isnan () de manera más eficiente para C ++ <cmath> que C <math.h>?

Aquí está mi código:

int f(double x)
{
  return isnan(x);
}

Si yo#include <cmath>&nbsp;Me sale esta asamblea:

xorl    %eax, %eax
ucomisd %xmm0, %xmm0
setp    %al

Esto es razonablemente inteligente:ucomisd&nbsp;establece el indicador de paridad si la comparación de x consigo misma no está ordenada, lo que significa que x es NAN. Entoncessetp&nbsp;copia el indicador de paridad en el resultado (solo un byte, de ahí el borrado inicial de%eax)

Pero si yo#include <math.h>&nbsp;Me sale esta asamblea:

jmp     __isnan

Ahora el código no está en línea, y el__isnan&nbsp;la función ciertamente no es más rápida que laucomisd&nbsp;instrucción, por lo que hemos incurrido en un salto sin beneficio. Me sale lo mismo si compilo el código como C.

Ahora si cambio elisnan()&nbsp;llamar a__builtin_isnan(), Me sale lo simpleucomisd&nbsp;instrucción, independientemente del encabezado que incluya, y también funciona en C. Del mismo modo si soloreturn x != x.

Entonces mi pregunta es, ¿por qué la C<math.h>&nbsp;el encabezado proporciona una implementación menos eficiente deisnan()&nbsp;que el C ++<cmath>&nbsp;¿encabezamiento? ¿Se espera que la gente realmente use__builtin_isnan()y si es así, ¿por qué?

Probé GCC 4.7.2 y 4.9.0 en x86-64 con-O2&nbsp;y-O3&nbsp;mejoramiento.