Namensräume
Varianten
Aktionen

Attribut-Spezifizierer-Sequenz (seit C++11)

Von cppreference.com
< cpp‎ | Sprache
 
 
C++ Sprache
Allgemeine Themen
Kontrollfluss
Bedingte Ausführungsaussagen
if
Iterationsanweisungen (Schleifen)
for
Bereichs-for (C++11)
Sprunganweisungen
Funktionen
Funktionsdeklaration
Lambda-Funktionsausdruck
inline-Spezifizierer
Dynamische Ausnahmespezifikationen (bis C++17*)
noexcept-Spezifizierer (C++11)
Ausnahmen
Namensräume
Typen
Spezifizierer
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Speicherdauer-Spezifizierer
Initialisierung
Ausdrücke
Alternative Darstellungen
Literale
Boolesch - Ganzzahl - Gleitkommazahl
Zeichen - String - nullptr (C++11)
Benutzerdefinierte (C++11)
Dienstprogramme
Attribute (C++11)
Typen
typedef-Deklaration
Typalias-Deklaration (C++11)
Umwandlungen
Speicherzuweisung
Klassen
Klassenspezifische Funktionseigenschaften
explicit (C++11)
static

Spezielle Member-Funktionen
Templates
Sonstiges
 
 
Attribute
(C++23)
(C++11)(bis C++26)
(C++14)
(C++20)
(C++17)
(C++11)
(C++20)
 

Führt implementierungsdefinierte Attribute für Typen, Objekte, Code usw. ein.

Inhalt

[bearbeiten] Syntax

[[ attributliste ]] (seit C++11)
[[ using attribut-namespace : attributliste ]] (seit C++17)

wobei attributliste eine durch Kommata getrennte Sequenz von null oder mehr attributen ist (die möglicherweise mit einer Auslassung ... endet, was eine Pack-Erweiterung anzeigt)

identifier (1)
attribut-namespace :: identifikator (2)
identifikator ( argumentliste (optional) ) (3)
attribut-namespace :: identifikator ( argumentliste (optional) ) (4)

wobei attribut-namespace ein identifikator ist und argumentliste eine Sequenz von Tokens ist, bei der Klammern, eckige Klammern und geschweifte Klammern ausgeglichen sind (ausgeglichene-token-sequenz).

1) Einfaches Attribut, wie z. B. [[noreturn]].
2) Attribut mit einem Namespace, wie z. B. [[gnu::unused]].
3) Attribut mit Argumenten, wie z. B. [[deprecated("weil")]].
4) Attribut sowohl mit einem Namespace als auch mit einer Argumentliste.

Wenn using namespace: am Anfang einer Attributliste erscheint, können keine anderen Attribute in der Attributliste einen Namespace angeben: der angegebene Namespace gilt für sie 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)

[bearbeiten] Erklärung

Attribute bieten die einheitliche Standard-Syntax für implementierungsdefinierte Spracherweiterungen, wie z. B. die GNU- und IBM-Spracherweiterungen __attribute__((...)), die Microsoft-Erweiterung __declspec() usw.

Ein Attribut kann fast überall im C++-Programm verwendet und auf fast alles angewendet werden: auf Typen, Variablen, Funktionen, Namen, Codeblöcke, ganze Übersetzungseinheiten, obwohl jedes spezifische Attribut nur dort gültig ist, wo es von der Implementierung zugelassen wird: [[expect_true]] könnte ein Attribut sein, das nur mit einem if verwendet werden kann und nicht mit einer Klassendeklaration. [[omp::parallel()]] könnte ein Attribut sein, das für einen Codeblock oder eine for-Schleife gilt, aber nicht für den Typ int usw. (beachten Sie, dass diese beiden Attribute fiktive Beispiele sind, siehe unten für die 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 unmittelbar vorangehende Entität.

Der alignas-Spezifizierer ist Teil der Attribut-Spezifizierer-Sequenz, obwohl er eine andere Syntax hat. Er kann dort erscheinen, wo die [[...]]-Attribute erscheinen, und kann mit ihnen vermischt werden (vorausgesetzt, er wird dort verwendet, wo alignas zulässig ist).

Zwei aufeinanderfolgende linke eckige Klammer-Tokens ([[) dürfen nur beim Einführen eines Attribut-Spezifizierers oder innerhalb eines Attributarguments erscheinen.

void f()
{
    int y[3];
    y[[] { return 0; }()] = 1;  // error
    int i [[cats::meow([[]])]]; // OK
}

Zusätzlich zu den unten aufgeführten Standardattributen können Implementierungen beliebige nicht-standardmäßige Attribute mit implementierungsdefinierten Verhaltensweisen unterstützen. Alle von einer Implementierung unbekannten Attribute werden ignoriert, ohne einen Fehler zu verursachen.(seit C++17)

Ein Attribut ohne attribut-namespace und ein attribut-namespace, dessen Name entweder std oder std gefolgt von einer oder mehreren Ziffern ist, ist für die zukünftige Standardisierung reserviert. Das heißt, jedes nicht-standardmäßige Attribut befindet sich im von der Implementierung bereitgestellten attribut-namespace, z. B. [[gnu::may_alias]], [[clang::trivial_abi]] und [[msvc::noop_dtor]].

(seit C++20)

[bearbeiten] Standardattribute

Die folgenden Attribute sind im C++-Standard definiert.

Standardattribute können nicht syntaktisch 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-used sein.

Standardattribute können auch semantisch nicht ignoriert werden: das Verhalten bei Entfernung aller Instanzen eines bestimmten Standardattributs wäre ein konformes Verhalten für das ursprüngliche Programm mit dem vorhandenen Attribut.

(C++11)
zeigt an, dass die Funktion nicht zurückkehrt
(Attribut-Spezifizierer)[bearbeiten]
(C++11)(entfernt in C++26)
zeigt an, dass die Abhängigkeitskette in Release-Consume std::memory_order in die und aus der Funktion propagiert
(Attribut-Spezifizierer)[bearbeiten]
[[deprecated]][[deprecated("Grund")]]
(C++14)(C++14)
zeigt an, dass die Verwendung des Namens oder der Entität, die mit diesem Attribut deklariert wurde, erlaubt, aber aus einem bestimmten Grund nicht empfohlen wird
(Attribut-Spezifizierer)[bearbeiten]
(C++17)
zeigt an, dass der Fall-Through vom vorherigen Case-Label beabsichtigt ist und von einem Compiler, der Fall-Through warnt, nicht diagnostiziert werden sollte
(Attribut-Spezifizierer)[bearbeiten]
(C++17)
unterdrückt Compiler-Warnungen bei unbenutzten Entitäten, falls vorhanden
(Attribut-Spezifizierer)[bearbeiten]
[[nodiscard]][[nodiscard("Grund")]]
(C++17)(C++20)
fordert den Compiler auf, eine Warnung auszugeben, wenn der Rückgabewert verworfen wird
(Attribut-Spezifizierer)[bearbeiten]
(C++20)(C++20)
zeigt an, dass der Compiler für den Fall optimieren sollte, dass ein Ausführungspfad durch eine Anweisung wahrscheinlicher oder unwahrscheinlicher ist als jeder andere Ausführungspfad
(Attribut-Spezifizierer)[bearbeiten]
zeigt an, dass ein nicht-statisches Datenelement keine Adresse haben muss, die sich von allen anderen nicht-statischen Datenelementen seiner Klasse unterscheidet
(Attribut-Spezifizierer)[bearbeiten]
[[assume(ausdruck)]]
(C++23)
spezifiziert, dass der ausdruck an einer gegebenen Stelle immer zu true ausgewertet wird
(Attribut-Spezifizierer)[bearbeiten]
(C++26)
spezifiziert, dass ein Objekt einen unbestimmten Wert hat, wenn es nicht initialisiert wird
(Attribut-Spezifizierer)[bearbeiten]
zeigt an, dass die Funktionsdefinition für die Aufrufe aus einer synchronized-Anweisung optimiert werden sollte
(Attribut-Spezifizierer)[bearbeiten]

[bearbeiten] Hinweise

Die Anwesenheit jedes einzelnen Attributs auf einer bestimmten Plattform kann mit dem Präprozessor-Makro __has_cpp_attribute überprüft werden.

Feature-Testmakro Wert Std Feature
__cpp_attributes 200809L (C++11) Attribute
__cpp_namespace_attributes 201411L (C++17) Attribute für Namespaces

[bearbeiten] Beispiel

[[gnu::always_inline]] [[gnu::hot]] [[gnu::const]] [[nodiscard]]
inline int f(); // declare f with four attributes
 
[[gnu::always_inline, gnu::const, gnu::hot, nodiscard]]
int f(); // same as above, but uses a single attr specifier that contains four attributes
 
// C++17:
[[using gnu : const, always_inline, hot]] [[nodiscard]]
int f[[gnu::always_inline]](); // an attribute may appear in multiple specifiers
 
int f() { return 0; }
 
int main() {}

[bearbeiten] Fehlerberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes 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 attributliste erscheinen nicht erforderlich.

[bearbeiten] Siehe auch

__has_cpp_attribute - prüft auf das Vorhandensein eines Attributs
C-Dokumentation für Attribut-Spezifizierer-Sequenz

[bearbeiten] Externe Links

1.  Attribute in GCC. Diese Attribute können als [[gnu::...]] verwendet werden, Siehe SO.
2.  Attribute in Clang.
3.  Attribute in MSVC.