Por que o GCC implementa isnan () com mais eficiência em C ++ <cmath> do que em C <math.h>?

Aqui está o meu código:

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

Se eu#include <cmath> Eu recebo esta montagem:

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

Isso é razoavelmente inteligente:ucomisd define o sinalizador de paridade se a comparação de x consigo não for ordenada, o que significa que x é NAN. Entãosetp copia o sinalizador de paridade no resultado (apenas um byte, portanto, a limpeza inicial de%eax)

Mas se eu#include <math.h> Eu recebo esta montagem:

jmp     __isnan

Agora o código não está embutido, e o__isnan função certamente não é mais rápido o doucomisd instruções, portanto, incorremos em um salto sem nenhum benefício. Eu recebo a mesma coisa se eu compilar o código como C.

Agora, se eu mudar oisnan() ligar para__builtin_isnan(), Eu entendo o simplesucomisd instrução instrução, independentemente de qual cabeçalho eu incluo, e funciona em C também. Da mesma forma, se eu apenasreturn x != x.

Então, minha pergunta é: por que o C<math.h> cabeçalho fornecem uma implementação menos eficiente deisnan() que o C ++<cmath> cabeçalho? As pessoas realmente devem usar__builtin_isnan()e, se sim, por quê?

Testei o GCC 4.7.2 e 4.9.0 em x86-64 com-O2 e-O3 otimização.

questionAnswers(1)

yourAnswerToTheQuestion