Attribute specifier sequence (since C++11)
Führt implementierungsdefinierte Attribute für Typen, Objekte, Code usw. ein.
Inhaltsverzeichnis |
Syntax
[[
Attributliste
]]
|
(seit C++11) | ||||||||
[[
using
Attributnamensraum
:
Attributliste
]]
|
(seit C++17) | ||||||||
wobei
attribute-list
eine durch Kommas getrennte Folge von null oder mehr
attribute
s ist (möglicherweise endend mit einer Auslassung
...
, die eine
pack expansion
anzeigt)
| Bezeichner | (1) | ||||||||
Attribut-Namensraum
::
Bezeichner
|
(2) | ||||||||
Bezeichner
(
Argumentenliste
(optional)
)
|
(3) | ||||||||
Attribut-Namensraum
::
Bezeichner
(
Argumentenliste
(optional)
)
|
(4) | ||||||||
wobei attribute-namespace ein identifier ist und argument-list eine Folge von Tokens ist, bei der Klammern, eckige Klammern und geschweifte Klammern ausgeglichen sind ( balanced-token-seq ).
|
Wenn
[[using CC: opt(1), debug]] // same as [[CC::opt(1), CC::debug]] [[using CC: CC::opt(1)]] // error: cannot combine using and scoped attribute |
(seit C++17) |
Erklärung
Attribute bieten die einheitliche Standardsyntax für implementierungsdefinierte Spracherweiterungen, wie die GNU- und IBM-Spracherweiterungen
__attribute__((...))
, Microsoft-Erweiterung
__declspec()
, usw.
Ein Attribut kann fast überall im C++-Programm verwendet werden und auf fast alles angewendet werden: auf Typen, auf Variablen, auf Funktionen, auf Namen, auf Codeblöcke, auf gesamte Übersetzungseinheiten, obwohl jedes bestimmte Attribut nur dort gültig ist, wo es durch die Implementierung erlaubt ist:
[[expect_true]]
könnte ein Attribut sein, das nur mit einer
if
-Anweisung verwendet werden kann, und nicht mit einer Klassendeklaration.
[[omp::parallel()]]
könnte ein Attribut sein, das auf einen Codeblock oder auf eine
for
-Schleife angewendet wird, aber nicht auf den Typ
int
, usw. (beachten Sie, dass diese beiden Attribute fiktive Beispiele sind, siehe unten für Standard- und einige nicht-standard Attribute).
In Deklarationen können Attribute sowohl vor der gesamten Deklaration als auch direkt nach dem Namen der deklarierten Entität erscheinen, in welchem Fall sie kombiniert werden. In den meisten anderen Situationen gelten Attribute für die direkt vorangehende Entität.
Der
alignas
-Spezifizierer
ist Teil der Attribut-Spezifizierer-Sequenz, obwohl er eine andere Syntax besitzt. Er kann dort erscheinen, wo die
[[...]]
-Attribute erscheinen, und kann mit ihnen gemischt werden (vorausgesetzt, er wird dort verwendet, wo
alignas
erlaubt ist).
Zwei aufeinanderfolgende linke eckige Klammern (
[[
) dürfen nur bei der Einführung eines Attribut-Spezifizierers oder innerhalb eines Attributarguments auftreten.
void f() { int y[3]; y[[] { return 0; }()] = 1; // Fehler int i [[cats::meow([[]])]]; // OK }
Zusätzlich zu den unten aufgeführten Standardattributen können Implementierungen beliebige nicht-standardisierte Attribute mit implementierungsdefiniertem Verhalten unterstützen. Alle einer Implementierung unbekannten Attribute werden ignoriert, ohne einen Fehler zu verursachen. (seit C++17)
|
Ein Attribut ohne
Attribut-Namensraum
und ein
Attribut-Namensraum
, dessen Name entweder
|
(since C++20) |
Standardattribute
Die folgenden Attribute sind durch den C++-Standard definiert.
Standardattribute können syntaktisch nicht ignoriert werden: Sie dürfen keine Syntaxfehler enthalten, müssen auf das korrekte Ziel angewendet werden, und Entitäten in den Argumenten müssen ODR-use sein.
Standardattribute können auch nicht semantisch ignoriert werden: Das Verhalten bei Entfernung aller Instanzen eines bestimmten Standardattributes wäre ein konformes Verhalten für das ursprüngliche Programm mit vorhandenem Attribut gewesen.
[[
noreturn
]]
(C++11)
|
gibt an, dass die Funktion nicht zurückkehrt
(Attributspezifizierer) |
[[
carries_dependency
]]
(C++11)
(entfernt in C++26)
|
gibt an, dass die Abhängigkeitskette in release-consume
std::memory_order
in die Funktion hinein und aus ihr heraus propagiert
(Attributspezifizierer) |
[[
deprecated
]]
[[
deprecated
("
reason
")]]
(C++14)
(C++14)
|
gibt an, dass die Verwendung des Namens oder der mit diesem Attribut deklarierten Entität erlaubt, aber aus einem
Grund
abgeraten wird
(Attributspezifizierer) |
[[
fallthrough
]]
(C++17)
|
gibt an, dass das Fallthrough vom vorherigen Case-Label beabsichtigt ist und nicht von einem Compiler diagnostiziert werden sollte, der vor Fallthrough warnt
(Attributspezifizierer) |
[[
maybe_unused
]]
(C++17)
|
unterdrückt Compiler-Warnungen zu ungenutzten Entitäten, falls vorhanden
(Attributspezifizierer) |
|
ermutigt den Compiler, eine Warnung auszugeben, wenn der Rückgabewert verworfen wird
(Attributspezifizierer) |
|
|
gibt an, dass der Compiler für den Fall optimieren sollte, dass ein Ausführungspfad durch eine Anweisung mehr oder weniger wahrscheinlich ist als jeder andere Ausführungspfad
(Attributspezifizierer) |
|
[[
no_unique_address
]]
(C++20)
|
gibt an, dass ein nicht-statisches Datenelement keine von allen anderen nicht-statischen Datenelementen seiner Klasse verschiedene Adresse haben muss
(Attributspezifizierer) |
[[
assume
(
expression
)]]
(C++23)
|
spezifiziert, dass der
Ausdruck
an einem gegebenen Punkt immer zu
true
ausgewertet wird
(Attributspezifizierer) |
[[
indeterminate
]]
(C++26)
|
spezifiziert, dass ein Objekt einen unbestimmten Wert hat, wenn es nicht initialisiert ist
(Attributspezifizierer) |
|
(TM TS)
|
gibt an, dass die Funktionsdefinition für den Aufruf aus einer
synchronized-Anweisung
optimiert werden sollte
(Attributspezifizierer) |
Hinweise
Das Vorhandensein jedes einzelnen Attributs auf einer bestimmten Plattform kann mit dem
__has_cpp_attribute
Präprozessor-Makro überprüft werden.
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_attributes
|
200809L
|
(C++11) | Attribute |
__cpp_namespace_attributes
|
201411L
|
(C++17) | Attribute für Namespaces |
Beispiel
[[gnu::always_inline]] [[gnu::hot]] [[gnu::const]] [[nodiscard]] inline int f(); // deklariere f mit vier Attributen [[gnu::always_inline, gnu::const, gnu::hot, nodiscard]] int f(); // wie oben, verwendet jedoch einen einzelnen Attributspezifizierer mit vier Attributen // C++17: [[using gnu : const, always_inline, hot]] [[nodiscard]] int f[[gnu::always_inline]](); // ein Attribut kann in mehreren Spezifizierern erscheinen int f() { return 0; } int main() {}
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| CWG 2079 | C++11 |
[[
konnte nicht innerhalb eines Attributarguments erscheinen
|
erlaubt |
| CWG 2538 | C++11 | es war unklar, ob Standardattribute syntaktisch ignoriert werden können | verboten |
| CWG 2695 | C++11 | es war unklar, ob Standardattribute semantisch ignoriert werden können | verboten |
| P2156R1 | C++11 | jedes Standardattribut musste höchstens einmal in einer attribute-list erscheinen | nicht erforderlich |
Siehe auch
__has_cpp_attribute
- prüft das Vorhandensein eines Attributes
|
|
|
C-Dokumentation
für
Attributspezifizierer-Sequenz
|
Externe Links
| 1. |
Attribute in GCC
. Diese Attribute können als
[[gnu::...]]
verwendet werden,
Siehe SO
.
|
| 2. | Attribute in Clang . |
| 3. | Attribute in MSVC . |