Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Der C++-Standard definiert allgemeine Attribute. Außerdem ermöglicht er Compilerherstellern, eigene Attribute in einem anbieterspezifischen Namespace zu definieren. Compiler sind jedoch nur erforderlich, um die im Standard definierten Attribute zu erkennen.
In einigen Fällen überschneiden sich Standardattribute mit compilerspezifischen -Parametern. In Microsoft C++ können Sie das -Attribut anstelle von verwenden. Das -Attribut wird von jedem konformen Compiler erkannt. Für alle anderen -Parameter wie und gibt es bisher keine Attributentsprechung. Daher müssen Sie die Syntax weiterhin verwenden . Attribute haben keinen Einfluss auf das Typsystem, und sie ändern die Bedeutung eines Programms nicht. Compiler ignorieren Attributwerte, die sie nicht erkennen.
Visual Studio 2017, Version 15.3 und höher (Verfügbar mit /std:c++17 und höher): Im Bereich einer Attributliste können Sie den Namespace für alle Namen mit einem einzelnen using Einführung angeben:
void g() {
[[using rpr: kernel, target(cpu,gpu)]] // equivalent to [[ rpr::kernel, rpr::target(cpu,gpu) ]]
do task();
}
C++-Standardattribute
In C++11 bieten Attribute eine standardisierte Möglichkeit, um zusätzliche Informationen zu C++-Konstrukten (unter anderem Klassen, Funktionen, Variablen und Blöcke) anzumerken. Attribute können anbieterspezifisch sein. Ein Compiler kann anhand dieser Informationen Informationsmeldungen generieren oder spezielle Logik beim Kompilieren des attributierten Codes anwenden. Der Compiler ignoriert alle nicht erkannten Attribute. Deshalb können Sie mit dieser Syntax keine eigenen benutzerdefinierten Attribute definieren. Attribute werden in doppelte eckige Klammern eingeschlossen:
[[deprecated]]
void Foo(int);
Attribute sind eine standardisierte Alternative zu anbieterspezifischen Erweiterungen wie -Anweisungen, (Visual C++) oder (GNU). Für die meisten Zwecke müssen Sie jedoch weiterhin die anbieterspezifischen Konstrukte verwenden. Der Standard gibt derzeit die folgenden Attribute an, die ein konformer Compiler erkennen sollte.
[[carries_dependency]]
Das -Attribut gibt an, dass die Funktion die Reihenfolge der Datenabhängigkeiten für die Threadsynchronisierung weitergibt. Das Attribut kann auf einen oder mehrere Parameter angewendet werden, um anzugeben, dass das übergebene Argument eine Abhängigkeit im Funktionstext enthält. Das Attribut kann auf die Funktion selbst angewendet werden, um anzugeben, dass der Rückgabewert eine Abhängigkeit aus der Funktion enthält. Der Compiler kann mithilfe dieser Informationen einen effizienteren Code generieren.
[[deprecated]]
Visual Studio 2015 und höher: Das Attribut [[deprecated]] gibt an, dass eine Funktion nicht für die Verwendung vorgesehen ist. oder dass es sie in künftigen Versionen einer Bibliotheksschnittstelle möglicherweise nicht mehr gibt. Das -Attribut kann auf die Deklaration einer Klasse, einen typedef-Namen, eine Variable, ein nicht statisches Datenelement, eine Funktion, einen Namespace, eine Enumeration, einen Enumerator oder eine Vorlagenspezialisierung angewendet werden. Der Compiler kann mit diesem Attribut eine Informationsmeldung generieren, wenn Clientcode versucht, die Funktion aufzurufen. Wenn der Microsoft C++-Compiler die Verwendung eines -Elements erkennt, löst er die Compilerwarnung C4996 aus.
[[fallthrough]]
Visual Studio 2017 und höher: (Verfügbar mit /std:c++17 und höher.) Das attribut [[fallthrough]] kann im Kontext von switch-Anweisungen als Hinweis für den Compiler (oder für jeden, der den Code liest) verwendet werden, dass das Verhalten der Fallthrough beabsichtigt ist. Der Microsoft C++-Compiler gibt derzeit keine Warnung Fall-Through-Verhalten aus. Daher hat dieses Attribut keine Auswirkungen auf das Compilerverhalten.
[[likely]]
Visual Studio 2019, Version 16.6 und höher: (Verfügbar mit /std:c++20 und höher.) Das Attribut [[likely]] gibt einen Hinweis auf den Compiler an, dass der Codepfad für die attributierten Bezeichnung oder Anweisung wahrscheinlicher ausgeführt wird als Alternativen. Im Microsoft-Compiler markiert das Attribut Blöcke als "Hot Code", wodurch eine interne Optimierungsbewertung erhöht wird. Die Bewertung wird bei einer Geschwindigkeitsoptimierung stärker erhöht als bei einer Größenoptimierung. Die Nettobewertung wirkt sich auf die Wahrscheinlichkeit von Inlining-, Loop-Unrolling- und Vektorisierungsoptimierungen aus. Die Wirkung von und ähnelt der profilgesteuerten Optimierung, ist jedoch vom Umfang her auf die aktuelle Übersetzungseinheit beschränkt. Die Optimierung der Blockneuanordnung ist für dieses Attribut noch nicht implementiert.
[[maybe_unused]]
Visual Studio 2017, Version 15.3 und höher: (Verfügbar mit /std:c++17 und höher.) Das Attribut [[maybe_unused]] gibt an, dass eine Variable, Funktion, Klasse, Typedef, nicht statische Datenmemmemm, Enumeration oder Vorlagenspezialisierung absichtlich nicht verwendet werden kann. Der Compiler gibt keine Warnung aus, wenn eine als markierte Entität nicht verwendet wird. Eine Entität, die ohne das Attribut deklariert wird, kann später mit dem Attribut neu deklariert werden und umgekehrt. Eine Entität wird als markiert betrachtet, nachdem ihre erste als markierte Deklaration analysiert wurde, sowie für den Rest der aktuellen Übersetzungseinheit.
[[nodiscard]]
Visual Studio 2017, Version 15.3 und höher: (Verfügbar mit /std:c++17 und höher.) Gibt an, dass der Rückgabewert einer Funktion nicht verworfen werden soll. Löst die Warnung C4834 aus, wie in diesem Beispiel gezeigt:
[[nodiscard]]
int foo(int i) { return i * i; }
int main()
{
foo(42); //warning C4834: discarding return value of function with 'nodiscard' attribute
return 0;
}
[[noreturn]]
Das -Attribut gibt an, dass eine Funktion niemals zurückgegeben wird, d. h., sie löst immer eine Ausnahme aus oder wird beendet. Der Compiler kann seine Kompilierungsregeln für -Entitäten anpassen.
[[unlikely]]
Visual Studio 2019, Version 16.6 und höher: (Verfügbar mit /std:c++20 und höher.) Das attribut [[unlikely]] gibt einen Hinweis für den Compiler an, dass der Codepfad für die attributierten Bezeichnung oder Anweisung weniger wahrscheinlich ausgeführt wird als Alternativen. Im Microsoft-Compiler markiert das -Attribut Blöcke als „Cold Code“, was eine interne Optimierungsbewertung schrittweise verringert. Die Bewertung wird bei einer Größenoptimierung stärker verringert als bei einer Geschwindigkeitsoptimierung. Die Nettobewertung wirkt sich auf die Wahrscheinlichkeit von Inlining-, Loop-Unrolling- und Vektorisierungsoptimierungen aus. Die Optimierung der Blockneuanordnung ist für dieses Attribut noch nicht implementiert.
Microsoft-spezifische Attribute
[[gsl::suppress(<tag> [, justification: <narrow-string-literal>])]]
Dieses microsoftspezifische Attribut, das in Visual Studio 2022, Version 17.14 eingeführt wurde, unterdrückt Warnungen von Prüfern, die Guidelines Support Library (GSL) Regeln erzwingen. Das Attribut kann auf eine Anweisung, einen Block oder eine Deklaration angewendet werden. Es ist nur für C++ verfügbar. Verwenden Sie stattdessen für C-Code.
ist eine Zeichenfolge, die den Namen der zu unterdrückenden Regel angibt. Im optionalen Feld können Sie erklären, warum eine Warnung deaktiviert oder unterdrückt wird. Dieser Wert wird im SARIF-Ausgabe (Static Analysis Results Interchange Format) angezeigt, wenn die Option angegeben wird. Sein Wert ist ein UTF-8-codiertes schmales Zeichenfolgenliteral. Verwenden Sie die Compileroption, um eine SARIF-Datei zu generieren.
Beispiel:
int main()
{
int arr[10]; // GSL warning C26494 will be fired
int* p = arr; // GSL warning C26485 will be fired
[[gsl::suppress("bounds.1", justification: "This attribute suppresses Bounds rule #1")]]
{
int* q = p + 1; // GSL warning C26481 suppressed
p = q--; // GSL warning C26481 suppressed
}
}
In diesem Beispiel werden die folgenden Warnungen ausgelöst:
- C26494 (Typregel 5: Ein Objekt immer initialisieren.)
- C26485 (Begrenzungsregel 3: Kein Array zum Zeigerzerfall.)
- C26481 (Begrenzungsregel 1: Keine Zeigerarithmetik verwenden. Stattdessen „span“ verwenden.)
Die ersten beiden Warnungen treten auf, wenn Sie diesen Code kompilieren, wobei das CppCoreCheck-Codeanalysetool installiert und aktiviert ist. Die dritte Warnung wird jedoch aufgrund des Attributs nicht ausgelöst. Sie können das gesamte Begrenzungsprofil unterdrücken, indem Sie schreiben, ohne eine bestimmte Regelnummer einzugeben. Die C++-Kernrichtlinien sind so konzipiert, dass Sie besseren und sichereren Code schreiben können. Das suppress-Attribut erleichtert das Deaktivieren unerwünschter Warnungen.
Wählen zwischen und
Beide und bieten eine fein abgestimmte Kontrolle über die Warnunterdrückung:
-
[[gsl::suppress]]unterdrückt nur Warnungen, die von Microsoft C++-Code Analysis ausgegeben werden. Verwenden Sie sie mit den C++-Kernrichtlinienprüfungen, die auf einen Bereich oder eine bestimmte Deklaration angewendet werden können. - kann für jede Compilerwarnung verwendet werden. Es ist nützlich, wenn Sie eine Warnung in einem bestimmten Codeblock unterdrücken müssen, ohne die Struktur des Codes erheblich zu ändern.
Verwenden Sie nach Möglichkeit [[gsl::suppress]], um Microsoft C++-Code Analysis Warnungen zu unterdrücken.
[[msvc::flatten]]
Das microsoftspezifische Attribut ähnelt und kann an den gleichen Stellen und auf die gleiche Weise verwendet werden. Der Unterschied besteht darin, dass rekursiv für alle Aufrufe in dem Bereich ausführt, auf den es angewendet wird, bis keine Aufrufe verbleiben. Dies kann hinsichtlich der resultierende Zunahme des Codeumfangs der Funktion oder des Compilerdurchsatzes Folgen haben, die Sie manuell behandeln müssen.
[[msvc::forceinline]]
Wenn das Microsoft-spezifische -Attribut vor einer Funktionsdeklaration platziert wird, hat es die gleiche Bedeutung wie .
[[msvc::forceinline_calls]]
Das Microsoft-spezifische -Attribut kann in einer Anweisung oder einem Block platziert werden oder davor. Die Inlineheuristik versucht, für alle Aufrufe in dieser Anweisung oder diesem Block auszuführen:
void f() {
[[msvc::forceinline_calls]]
{
foo();
bar();
}
...
[[msvc::forceinline_calls]]
bar();
foo();
}
Der erste Aufruf von und beide Aufrufe von werden so behandelt, als würden sie mit deklariert werden. Der zweite Aufruf von wird nicht als behandelt.
[[msvc::intrinsic]]
Das -Attribut bringt für die Funktion, auf die es angewendet wird, drei Einschränkungen mit sich:
- Die Funktion kann nicht rekursiv sein; ihr Textkörper darf nur über eine return-Anweisung mit einem vom Parametertyp bis zum Rückgabetyp verfügen.
- Die Funktion kann nur einen einzigen Parameter akzeptieren.
- Die Compileroption ist erforderlich. ( und spätere Optionen schließen standardmäßig ein.)
Das Microsoft-spezifische -Attribut weist den Compiler an, inline eine Metafunktion zu verwenden, die als benannte Umwandlung vom Parametertyp in den Rückgabetyp fungiert. Wenn das Attribut in einer Funktionsdefinition vorhanden ist, ersetzt der Compiler alle Aufrufe dieser Funktion durch eine einfache Umwandlung. Das attribut [[msvc::intrinsic]] ist in Visual Studio 2022, Version 17.5 Preview 2 und höher, verfügbar. Dieses Attribut gilt nur für die darauf folgende bestimmte Funktion.
Beispiel
In diesem Beispielcode veranlasst das -Attribut, das auf die -Funktion angewendet wird, den Compiler zum Ersetzen von Aufrufen der Funktion durch die inline im Textkörper enthaltene statische Umwandlung:
template <typename T>
[[msvc::intrinsic]] T&& my_move(T&& t) { return static_cast<T&&>(t); }
void f() {
int i = 0;
i = my_move(i);
}
[[msvc::musttail]]
Das in MSVC Build Tools Version 14.50 eingeführte Attribut ist ein experimentelles x64-only Microsoft-spezifisches Attribut, das die Tail-Call-Optimierung erzwingt. Wenn sie auf eine qualifizierende Rückgabeanweisung angewendet wird, weist sie den Compiler an, den Aufruf als Tail-Aufruf auszugeben. Wenn der Compiler den Tail-Aufruf nicht ausgeben kann, erzeugt er einen Kompilierungsfehler. Das Attribut erzwingt einen Tail-Aufruf, anstatt die Funktion zu inlineieren.
Anforderungen:
- Der Anrufer und der Angerufene müssen übereinstimmende Rückgabetypen haben.
- Die Aufrufkonventionen müssen kompatibel sein.
- Der Tail-Aufruf muss die letzte Aktion in der aufrufenden Funktion sein.
- Der Angerufene kann nicht mehr Stapelplatz als die aufrufende Funktion verwenden.
- Wenn mehr als vier ganzzahlige Parameter übergeben werden, muss die aufrufende Funktion genügend Stapelplatz für die anderen Argumente zuweisen.
- Kompilieren mit oder Optimierungsebene.
Beispiel
Tail-Aufrufe sind eine Compileroptimierung, die möglich ist, wenn ein Funktionsaufruf die letzte Aktion ist, die vor der Rückgabe ausgeführt wird. Anstatt einen neuen Stapelframe zum Aufrufen der Funktion zu erstellen, wird der Stapelframe der aktuellen Funktion wiederverwendet. Dies reduziert die Stapelnutzung und verbessert die Leistung – insbesondere in rekursiven Szenarien.
Im folgenden Code bewirkt das angewendete Attribut, dass die Steuerung direkt auf . Wenn die Anweisung erreicht wird, wird das Ergebnis direkt an den Aufrufer von , d . h. Dadurch wird das Ein- oder Aufrufen von und das Aufrufen von und vor der Rückkehr zu . Die Tail Call-Optimierung beseitigt die Notwendigkeit , die Kontrolle nach Abschluss wieder zu erlangen. Dies ist eine Leistungsoptimierung, die die Stapelnutzung reduziert, insbesondere bei rekursiven Szenarien.
// compile with /O2
#include <iostream>
int increment(int x)
{
return x + 1;
}
int incrementIfPositive(int x)
{
if (x > 0)
{
[[msvc::musttail]]
return increment(x);
}
return -1;
}
int main()
{
int result = incrementIfPositive(42);
if (result < 0)
{
return -1;
}
std::cout << result; // outputs 43
return 0;
}
[[msvc::noinline]]
Wenn das Microsoft-spezifische -Attribut vor einer Funktionsdeklaration platziert wird, hat es die gleiche Bedeutung wie .
[[msvc::noinline_calls]]
Das Microsoft-spezifische -Attribut wird genau so verwendet wie . Es kann vor einer Anweisung oder einem Block platziert werden. Anstatt die Inlineverwendung aller Aufrufe in diesem Block zu erzwingen, deaktiviert es das Inlining für den Bereich, auf den es angewendet wird.
[[msvc::no_tls_guard]]
Das Microsoft-spezifische -Attribut deaktiviert die Überprüfung der Initialisierung beim ersten Zugriff auf threadlokale Variablen in DLLs. Die Prüfungen sind standardmäßig in Code aktiviert, der mit Visual Studio 2019, Version 16.5 und höher, erstellt wurde. Dieses Attribut gilt nur für die darauf folgenden bestimmten Variablen. Verwenden Sie die Compileroption , um Überprüfungen global zu deaktivieren.