Warum implementiert GCC isnan () effizienter für C ++ <cmath> als C <math.h>?

Hier ist mein Code:

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

Wenn ich#include <cmath> Ich bekomme diese Assembly:

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

Das ist einigermaßen schlau: ucomisd setzt das Paritätsflag, wenn der Vergleich von x mit sich selbst ungeordnet ist, was bedeutet, dass x NAN ist. Dann setp kopiert das Paritätsflag in das Ergebnis (nur ein einziges Byte, daher das anfängliche Löschen von%eax).

Aber wenn ich#include <math.h> Ich bekomme diese Assembly:

jmp     __isnan

Jetzt ist der Code nicht inline und das__isnan funktion geht bestimmt nicht schneller das dasucomisd Anweisung, so haben wir einen Sprung ohne Nutzen entstanden. Ich bekomme das gleiche, wenn ich den Code als C kompiliere.

Nun wenn ich das @ ändeisnan() Aufruf__builtin_isnan(), Ich bekomme die einfacheucomisd Befehl Befehl, unabhängig davon, welchen Header ich einbinde, und er funktioniert auch in C. Ebenso, wenn ich nurreturn x != x.

So ist meine Frage, warum das C<math.h> header bietet eine weniger effiziente Implementierung vonisnan() als das C ++<cmath> Header? Wird von den Leuten wirklich erwartet, dass sie @ verwende__builtin_isnan() und wenn ja, warum?

Ich habe GCC 4.7.2 und 4.9.0 auf x86-64 mit @ geteste-O2 und-O3 Optimierung.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage