Namespaces
Variants

Attribute specifier sequence (since C23)

From cppreference.net

Führt implementierungsdefinierte Attribute für Typen, Objekte, Ausdrücke etc. ein.

Inhaltsverzeichnis

Syntax

[[ attr  ]] [[ attr1 , attr2 , attr3 ( args ) ]] [[ attribute-prefix :: attr  ( args ) ]]
**Anmerkung:** Da der Text ausschließlich aus C++-Attributsyntax besteht und gemäß den Anweisungen keine HTML-Tags, Code-Blöcke oder C++-spezifischen Begriffe übersetzt werden sollen, bleibt der gesamte Inhalt unverändert. Die dargestellten Attribute-Syntax-Beispiele sind bereits in ihrer technisch korrekten Form und erfordern keine Übersetzung.

Formal lautet die Syntax

[[ Attributliste ]] (seit C23)

wobei attribute-list eine durch Kommas getrennte Folge von null oder mehr attribute-token s ist

Standardattribut (1)
Attributpräfix :: Bezeichner (2)
Standardattribut ( Argumentenliste  (optional) ) (3)
Attributpräfix :: Bezeichner ( Argumentenliste  (optional) ) (4)

wobei attribute-prefix ein identifier ist und argument-list eine Folge von Tokens ist, bei der Klammern, eckige Klammern und geschweifte Klammern ausgeglichen sind ( balanced-token-sequence ).

1) Standard-Attribut, wie [ [ fallthrough ] ]
2) Attribut mit einem Namensraum, wie [ [ gnu :: unused ] ]
3) Standard-Attribut mit Argumenten, wie [ [ deprecated ( "reason" ) ] ]
4) Attribut mit sowohl einem Namensraum als auch einer Argumentliste, wie [ [ gnu :: nonnull ( 1 ) ] ]

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 werden kann, 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.

Zwei aufeinanderfolgende linke eckige Klammern ( [[ ) dürfen nur bei der Einführung eines Attribut-Spezifizierers oder innerhalb eines Attributarguments auftreten.

Neben 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.

Jeder standard-attribute ist für die Standardisierung reserviert. Das bedeutet, jedes nicht-standard Attribut wird durch einen attribute-prefix präfixiert, der durch die Implementierung bereitgestellt wird, z.B. [[gnu::may_alias]] und [[clang::no_sanitize]] .

Standardattribute

Nur die folgenden Attribute sind durch den C-Standard definiert. Jedes Standardattribut, dessen Name die Form attr hat, kann auch als __attr__ geschrieben werden und seine Bedeutung ändert sich nicht.

[[ deprecated ]] (C23) [[ deprecated (" reason ")]] (C23)
zeigt an, dass die Verwendung des Namens oder der Entität, die mit diesem Attribut deklariert wurde, erlaubt ist, jedoch aus einem bestimmten Grund abgeraten wird
(Attributspezifizierer)
(C23)
zeigt an, dass das Fallthrough vom vorherigen Case-Label beabsichtigt ist und nicht von einem Compiler diagnostiziert werden sollte, der vor Fallthrough warnt
(Attributspezifizierer)
[[ nodiscard ]] (C23) [[ nodiscard (" reason ")]] (C23)
ermutigt den Compiler, eine Warnung auszugeben, wenn der Rückgabewert verworfen wird
(Attributspezifizierer)
(C23)
unterdrückt Compiler-Warnungen bei ungenutzten Entitäten, falls vorhanden
(Attributspezifizierer)
[[ noreturn ]] (C23) [[ _Noreturn ]] (C23) (deprecated)
zeigt an, dass die Funktion nicht zurückkehrt
(Attributspezifizierer)
(C23)
zeigt an, dass eine Funktion zustandslos, wirkungslos, idempotent und unabhängig ist
(Attributspezifizierer)
(C23)
zeigt an, dass eine Funktion wirkungslos und idempotent ist
(Attributspezifizierer)

Attributprüfung

__has_c_attribute( Attribut-Token )

Prüft das Vorhandensein eines Attributtokens mit dem Namen attribute-token .

Für Standardattribute wird es auf das Jahr und den Monat erweitert, in dem das Attribut zum Arbeitsentwurf hinzugefügt wurde (siehe Tabelle unten), das Vorhandensein von herstellerspezifischen Attributen wird durch eine ganzzahlige Konstante ungleich Null bestimmt.

__has_c_attribute kann im Ausdruck von #if und #elif expandiert werden. Es wird als definiertes Makro behandelt von #ifdef , #ifndef und defined , kann aber nirgendwo anders verwendet werden.

attribute-token Attribut Wert Standard
deprecated [[ deprecated ]] 201904L (C23)
fallthrough [[ fallthrough ]] 201904L (C23)
maybe_unused [[ maybe_unused ]] 201904L (C23)
nodiscard [[ nodiscard ]] 202003L (C23)
noreturn
_Noreturn
[[ noreturn ]]
[[ _Noreturn ]]
202202L (C23)
unsequenced [[ unsequenced ]] 202207L (C23)
reproducible [[ reproducible ]] 202207L (C23)

Beispiel

[[gnu::hot]] [[gnu::const]] [[nodiscard]]
int f(void); // deklariere f mit drei Attributen
[[gnu::const, gnu::hot, nodiscard]]
int f(void); // dasselbe wie oben, verwendet jedoch einen einzelnen Attribut-
             // Spezifizierer, der drei Attribute enthält
int f(void) { return 0; }
int main(void)
{
}

Referenzen

  • C23-Standard (ISO/IEC 9899:2024):
  • 6.7.12 Attribute (S: TBD)

Siehe auch

C++ Dokumentation für Attributspezifizierer-Sequenz

Externe Links

1. Attribute in GCC
2. Attribute in Clang