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

Introduit des attributs définis par l'implémentation pour les types, les objets, le code, etc.

Table des matières

Syntaxe

[[ liste-attributs ]] (depuis C++11)
[[ using espace-noms-attributs : liste-attributs ]] (depuis C++17)

attribute-list est une séquence séparée par des virgules de zéro ou plusieurs attribute s (pouvant se terminer par des points de suspension ... indiquant une pack expansion )

identifiant (1)
espace-de-noms-attribut :: identifiant (2)
identifiant ( liste-arguments  (optionnel) ) (3)
espace-de-noms-attribut :: identifiant ( liste-arguments  (optionnel) ) (4)

attribute-namespace est un identifiant et argument-list est une séquence de jetons où les parenthèses, crochets et accolades sont équilibrés ( balanced-token-seq ).

1) Attribut simple, tel que [ [ noreturn ] ] .
2) Attribut avec un espace de noms, tel que [ [ gnu :: unused ] ] .
3) Attribut avec arguments, tel que [ [ deprecated ( "because" ) ] ] .
4) Attribut avec à la fois un espace de noms et une liste d'arguments.

Si using namespace: apparaît au début d'une liste d'attributs, aucun autre attribut dans la liste d'attributs ne peut spécifier un espace de noms : l'espace de noms spécifié dans un using s'applique à tous :

[[using CC: opt(1), debug]] // same as [[CC::opt(1), CC::debug]]
[[using CC: CC::opt(1)]] // error: cannot combine using and scoped attribute
(depuis C++17)

Explication

Les attributs fournissent la syntaxe standard unifiée pour les extensions de langage définies par l'implémentation, telles que les extensions de langage GNU et IBM __attribute__((...)) , l'extension Microsoft __declspec() , etc.

Un attribut peut être utilisé presque partout dans le programme C++, et peut être appliqué à presque tout : aux types, aux variables, aux fonctions, aux noms, aux blocs de code, aux unités de traduction entières, bien que chaque attribut particulier ne soit valide que là où il est permis par l'implémentation : [[expect_true]] pourrait être un attribut qui ne peut être utilisé qu'avec une instruction if , et non avec une déclaration de classe. [[omp::parallel()]] pourrait être un attribut qui s'applique à un bloc de code ou à une boucle for , mais pas au type int , etc (notez que ces deux attributs sont des exemples fictifs, voir ci-dessous pour les attributs standard et non standard).

Dans les déclarations, les attributs peuvent apparaître à la fois avant la déclaration entière et directement après le nom de l'entité qui est déclarée, auquel cas ils sont combinés. Dans la plupart des autres situations, les attributs s'appliquent à l'entité directement précédente.

Le alignas spécificateur fait partie de la séquence de spécificateurs d'attributs, bien qu'il ait une syntaxe différente. Il peut apparaître là où les attributs [[...]] apparaissent et peut se mélanger avec eux (à condition qu'il soit utilisé là où alignas est autorisé).

Deux jetons consécutifs de crochet gauche ( [[ ) ne peuvent apparaître que lors de l'introduction d'un spécificateur d'attribut ou à l'intérieur d'un argument d'attribut.

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

En plus des attributs standard listés ci-dessous, les implémentations peuvent supporter des attributs non standard arbitraires avec un comportement défini par l'implémentation. Tous les attributs inconnus d'une implémentation sont ignorés sans provoquer d'erreur. (depuis C++17)

Un attribut sans attribute-namespace et un attribute-namespace dont le nom est soit std soit std suivi d'un ou plusieurs chiffres est réservé pour une standardisation future. Autrement dit, tout attribut non standard se trouve dans le attribute-namespace fourni par l'implémentation, par exemple [[gnu::may_alias]] , [[clang::trivial_abi]] , et [[msvc::noop_dtor]] .

(depuis C++20)

Attributs standard

Les attributs suivants sont définis par la norme C++.

Les attributs standards ne peuvent pas être syntaxiquement ignorés : ils ne peuvent pas contenir d'erreurs de syntaxe, doivent être appliqués à la cible correcte, et les entités dans les arguments doivent être ODR-use .

Les attributs standards ne peuvent pas non plus être sémantiquement ignorés : le comportement avec toutes les instances d'un attribut standard particulier supprimées aurait été un comportement conforme pour le programme original avec l'attribut présent.

(C++11)
indique que la fonction ne retourne pas
(spécificateur d'attribut)
(C++11) (supprimé en C++26)
indique que la chaîne de dépendance dans release-consume std::memory_order se propage à l'intérieur et à l'extérieur de la fonction
(spécificateur d'attribut)
[[ deprecated ]] [[ deprecated (" reason ")]]
(C++14) (C++14)
indique que l'utilisation du nom ou de l'entité déclaré avec cet attribut est autorisée, mais déconseillée pour une certaine raison
(spécificateur d'attribut)
(C++17)
indique que la chute depuis l'étiquette de cas précédente est intentionnelle et ne devrait pas être diagnostiquée par un compilateur qui avertit sur les chutes
(spécificateur d'attribut)
(C++17)
supprime les avertissements du compilateur sur les entités non utilisées, le cas échéant
(spécificateur d'attribut)
[[ nodiscard ]] [[ nodiscard (" reason ")]]
(C++17) (C++20)
encourage le compilateur à émettre un avertissement si la valeur de retour est ignorée
(spécificateur d'attribut)
(C++20) (C++20)
indique que le compilateur doit optimiser pour le cas où un chemin d'exécution à travers une instruction est plus ou moins probable que tout autre chemin d'exécution
(spécificateur d'attribut)
(C++20)
indique qu'un membre de données non statique n'a pas besoin d'avoir une adresse distincte de tous les autres membres de données non statiques de sa classe
(spécificateur d'attribut)
[[ assume ( expression )]]
(C++23)
spécifie que l' expression s'évaluera toujours à true à un point donné
(spécificateur d'attribut)
(C++26)
spécifie qu'un objet a une valeur indéterminée s'il n'est pas initialisé
(spécificateur d'attribut)
indique que la définition de la fonction doit être optimisée pour l'invocation depuis une instruction synchronisée
(spécificateur d'attribut)

Notes

La présence de chaque attribut individuel sur une plateforme donnée peut être vérifiée avec __has_cpp_attribute la macro de préprocesseur.

Macro de test de fonctionnalité Valeur Std Fonctionnalité
__cpp_attributes 200809L (C++11) Attributs
__cpp_namespace_attributes 201411L (C++17) Attributs pour espaces de noms

Exemple

[[gnu::always_inline]] [[gnu::hot]] [[gnu::const]] [[nodiscard]]
inline int f(); // déclare f avec quatre attributs
[[gnu::always_inline, gnu::const, gnu::hot, nodiscard]]
int f(); // identique à ci-dessus, mais utilise un seul spécificateur d'attribut contenant quatre attributs
// C++17 :
[[using gnu : const, always_inline, hot]] [[nodiscard]]
int f[[gnu::always_inline]](); // un attribut peut apparaître dans plusieurs spécificateurs
int f() { return 0; }
int main() {}

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Appliqué à Comportement publié Comportement corrigé
CWG 2079 C++11 [[ ne pouvait pas apparaître dans un argument d'attribut autorisé
CWG 2538 C++11 il n'était pas clair si les attributs standards pouvaient être ignorés syntaxiquement interdit
CWG 2695 C++11 il n'était pas clair si les attributs standards pouvaient être ignorés sémantiquement interdit
P2156R1 C++11 chaque attribut standard devait apparaître au plus une fois dans une attribute-list non requis

Voir aussi

__has_cpp_attribute - vérifie la présence d'un attribut
Documentation C pour Séquence de spécificateurs d'attributs

Liens externes

1. Attributs dans GCC . Ces attributs peuvent être utilisés comme [[gnu::...]] , Voir SO .
2. Attributs dans Clang .
3. Attributs dans MSVC .