Attribute specifier sequence (since C23)
Führt implementierungsdefinierte Attribute für Typen, Objekte, Ausdrücke etc. ein.
Inhaltsverzeichnis |
Syntax
-
[[attr ]][[attr1 , attr2 , attr3(args)]][[attribute-prefix::attr (args)]]
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 ).
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) |
[[
fallthrough
]]
(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) |
|
ermutigt den Compiler, eine Warnung auszugeben, wenn der Rückgabewert verworfen wird
(Attributspezifizierer) |
|
[[
maybe_unused
]]
(C23)
|
unterdrückt Compiler-Warnungen bei ungenutzten Entitäten, falls vorhanden
(Attributspezifizierer) |
|
zeigt an, dass die Funktion nicht zurückkehrt
(Attributspezifizierer) |
|
[[
unsequenced
]]
(C23)
|
zeigt an, dass eine Funktion zustandslos, wirkungslos, idempotent und unabhängig ist
(Attributspezifizierer) |
[[
reproducible
]]
(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 |