pure/const-Funktion von Attributen in verschiedenen Compilern
Reine ist eine Funktion, Attribut, welches sagt, dass eine Funktion nicht ändern globalen Speicher.
const ist eine Funktion, Attribut, welches sagt, dass eine Funktion keine Lesen/ändern keine globalen Speicher.
Gegeben, dass die Informationen, die der compiler kann einige zusätzliche Optimierungen.
Beispiel für GCC:
float sigmoid(float x) __attribute__ ((const));
float calculate(float x, unsigned int C) {
float sum = 0;
for(unsigned int i = 0; i < C; ++i)
sum += sigmoid(x);
return sum;
}
float sigmoid(float x) { return 1.0f / (1.0f - exp(-x)); }
In diesem Beispiel der compiler könnte die Optimierung der Funktion berechnen zu:
float calculate(float x, unsigned int C) {
float sum = 0;
float temp = C ? sigmoid(x) : 0.0f;
for(unsigned int i = 0; i < C; ++i)
sum += temp;
return sum;
}
Oder wenn Ihr compiler clever genug ist (und nicht so streng über Fließkommazahlen (floats):
float calculate(float x, unsigned int C) { return C ? sigmoid(x) * C : 0.0f; }
Wie kann ich markieren Sie eine Funktion in einer solchen Art und Weise für die verschiedenen Compiler, d.h. GCC, Clang, ICC, MSVC oder andere?
- Für diejenigen von uns, die nicht mit gcc auf einer regelmäßigen basis, vielleicht kannst du eine Erklärung, was die Reine/const-Attribut ist. Wenn es sich um eine Optimierung von einer Art, ein Beispiel für C-oder C++ - code, für die es hilft dem compiler generieren mehr optimale Montage wäre auch hilfreich.
- Ich bin kein compiler-Schriftsteller, aber es scheint mir, dass solch ein Attribut wäre unnötig, wenn die
sigmoid()
Funktion definition zur Verfügung Stand, ist der compiler vor der Analysecalculate()
in der gleichen übersetzungseinheit. Egal, diese Attribute könnte sicherlich nützlich sein, wenn Sie die Funktion Definitionen sind in verschiedene übersetzungseinheiten. - Ja, GCC (und andere Compiler) automatisch hinzufügen dieses Attribut intern genau in diesem Fall. Und dann, auf der Grundlage der attribute, die Sie tun können, weitere Optimierungen (wie in meinem Beispiel). Und Sie genau trifft einer der wichtigsten Gründe für die Angabe, es gilt: Wenn der compiler nicht sieht, dass die definition an dieser Stelle oder, wenn die definition ist überhaupt nicht verfügbar, oder wenn Sie denken, dass es sicher ist, wenn der compiler reduziert die Menge der Aufrufe der Funktion.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Im Allgemeinen, es scheint, dass fast alle Compiler unterstützen den GCC Parametern. MSVC ist bisher der einzige compiler, die Sie nicht unterstützt (und auch keine alternative).
#if __GNUC__ > 4 || ...
oder ähnliches, empfohlen in der Bedienungsanleitung. Clang (und andere Compiler) nur Werbung für eine__GNUC__
und__GNUC_MINOR__
version, die Sie voll unterstützen. Die Umsetzung könnte von gcc (z.B. clang ist__builtin_constant_p()
nicht propagieren const-ness in Funktion args von inline-Funktionen), aber dein code kompiliert wird.__GNUC__
6 und__GNUC_MINOR__
0 in Versionen mit Unterstützung der alle - die Sprache Erweiterungen, die gcc6.0 macht.Erstens, es ist nützlich, zu beachten, dass "const" ist eine schärfere version
"rein", also "rein" kann als fallback verwendet werden, wenn ein compiler nicht
Umsetzung der "const".
Wie andere erwähnt haben, MSVC nicht wirklich was ähnliches,
aber eine Menge von Compilern angenommen haben, die GCC-syntax, darunter viele
die definieren nicht
__GNUC__
(und einige, die sich ab undmanchmal nicht, je nach flags).
rein
da 2.96+, und
const
seit 2.5.0, in Fall, dass Sie fühlen, wie das überprüfen der version.
__has_attribute(pure)
und__has_attribute(const)
um Sie zu erkennen, aber es ist wohl fein zuVerlass dich einfach auf clang Einstellung
__GNUC__
. Dies beinhaltet auch Compilerbasierend auf clang wie emscripten und XL C/C++ 13+.
schrecklich, so habe ich keine Ahnung, Wann Sie Hinzugefügt wurden. 16.0+ ist sicher
sicher.
rein
und
const
mit gcc --(erkannt mit
__TI_GNU_ATTRIBUTE_SUPPORT__
) unterstützt.mindestens stillschweigend ignoriert). 17.10+ ist sicher, aber Sie haben wahrscheinlich
akzeptabel für viel mehr.
Dieser, die klappern immer definiert
__GNUC__
und Freunde (derzeit4.2, IIRC). Intel definiert
__GNUC__
standardmäßig (obwohl es sein kann,unterdrückt -Nein-gcc) und g.g.A., in der C++ - Modus (aber nicht in C
Modus). Die andere, die Sie haben zu prüfen manuell.
Oracle Developer Studio hat auch unterstützte pragmas, da es bekannt war,
als Forte Developer
6. Sie sind
ein bisschen anders, da Sie erfordern Sie, um die Funktion anzugeben
name:
TI 6.0+ (mindestens) unterstützt eine
#pragma FUNC_IS_PURE;
pragma in C++Modus nur. Im C-Modus, es ist
#pragma FUNC_IS_PURE(funcname);
.Meisten dieser kann ausgeblendet werden, hinter die ein makro, was ich auch gemacht habe
Hedley:
Dies beinhaltet noch nicht die Varianten, die erfordern würde, die Funktion
Namen als argument, aber es immer noch deckt die große Mehrheit der
Benutzer, und es ist sicher, überall zu verwenden.
Wenn Sie nicht möchten, zu verwenden, Hedley (es ist ein single-public domain /CC0-header) es
sollte nicht allzu schwierig sein, Sie zu ersetzen der internen version der Makros. Wenn
Sie beschließen, das zu tun, sollten Sie wahrscheinlich die Basis-Anschluss auf der
Hedley repo-statt dieser Antwort, als ich bin viel eher, es zu halten
up-to-date.