Attribute specifier sequence (since C++11)
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) | ||||||||
où
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) | ||||||||
où 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 ).
|
Si
[[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
|
(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.
[[
noreturn
]]
(C++11)
|
indique que la fonction ne retourne pas
(spécificateur d'attribut) |
[[
carries_dependency
]]
(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) |
[[
fallthrough
]]
(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) |
[[
maybe_unused
]]
(C++17)
|
supprime les avertissements du compilateur sur les entités non utilisées, le cas échéant
(spécificateur d'attribut) |
|
encourage le compilateur à émettre un avertissement si la valeur de retour est ignorée
(spécificateur d'attribut) |
|
|
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) |
|
[[
no_unique_address
]]
(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) |
[[
indeterminate
]]
(C++26)
|
spécifie qu'un objet a une valeur indéterminée s'il n'est pas initialisé
(spécificateur d'attribut) |
|
(TM TS)
|
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 . |