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.