Namespaces
Variants

Attribute specifier sequence (since C++11)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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

1) Einfaches Attribut, wie [ [ noreturn ] ] .
2) Attribut mit einem Namensraum, wie [ [ gnu :: unused ] ] .
3) Attribute mit Argumenten, wie [ [ deprecated ( "because" ) ] ] .
4) Attribut mit sowohl einem Namensraum als auch einer Argumentliste.

Wenn using namespace: am Anfang einer Attributliste erscheint, dürfen keine anderen Attribute in der Attributliste einen Namespace angeben: Der in einem using angegebene Namespace gilt für alle:

[[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 std oder std gefolgt von einer oder mehreren Ziffern ist, ist für zukünftige Standardisierung reserviert. Das heißt, jedes nicht-standard Attribut befindet sich im Attribut-Namensraum , der durch die Implementierung bereitgestellt wird, z.B. [[gnu::may_alias]] , [[clang::trivial_abi]] , und [[msvc::noop_dtor]] .

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

(C++11)
gibt an, dass die Funktion nicht zurückkehrt
(Attributspezifizierer)
(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)
(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)
(C++17)
unterdrückt Compiler-Warnungen zu ungenutzten Entitäten, falls vorhanden
(Attributspezifizierer)
[[ nodiscard ]] [[ nodiscard (" reason ")]]
(C++17) (C++20)
ermutigt den Compiler, eine Warnung auszugeben, wenn der Rückgabewert verworfen wird
(Attributspezifizierer)
(C++20) (C++20)
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)
(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)
(C++26)
spezifiziert, dass ein Objekt einen unbestimmten Wert hat, wenn es nicht initialisiert ist
(Attributspezifizierer)
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 .