attribute-specifier-seq: attribute-specifier-seq attribute-specifier
attribute-specifier: [ [ attribute-using-prefix attribute-list ] ] alignment-specifier
alignment-specifier: alignas ( type-id ... ) alignas ( constant-expression ... )
attribute-using-prefix: using attribute-namespace :
attribute-list: attribute attribute-list , attribute attribute ... attribute-list , attribute ...
attribute: attribute-token attribute-argument-clause
attribute-token: identifier attribute-scoped-token
attribute-scoped-token: attribute-namespace :: identifier
attribute-namespace: identifier
attribute-argument-clause: ( balanced-token-seq )
balanced-token-seq: balanced-token balanced-token-seq balanced-token
balanced-token: ( balanced-token-seq ) [ balanced-token-seq ] { balanced-token-seq } any token other than a parenthesis, a bracket, or a brace
[[using CC: opt(1), debug]] // same as [[CC::opt(1), CC::debug]] void f() {} [[using CC: opt(1)]] [[CC::debug]] // same as [[CC::opt(1)]] [[CC::debug]] void g() {} [[using CC: CC::opt(1)]] // error: cannot combine using and scoped attribute token void h() {}— end example
int p[10];
void f() {
int x = 42, y[5];
int(p[[x] { return x; }()]); // error: invalid attribute on a nested declarator-id and
// not a function-style cast of an element of p.
y[[] { return 2; }()] = 2; // error even though attributes are not allowed in this context.
int i [[vendor::attr([[]])]]; // well-formed implementation-defined attribute.
} — end example
struct alignas(8) S {};
struct alignas(1) U {
S s;
}; // error: U specifies an alignment that is less strict than if the alignas(1) were omitted.
— end example// Translation unit #1: struct S { int x; } s, *p = &s; // Translation unit #2: struct alignas(16) S; // error: definition of S lacks alignment, no diagnostic required extern S* p;— end example
alignas(T) alignas(A) T buffer[N];Specifying alignas(T) ensures that the final requested alignment will not be weaker than alignof(T), and therefore the program will not be ill-formed.
alignas(double) void f(); // error: alignment applied to function alignas(double) unsigned char c[sizeof(double)]; // array of characters, suitably aligned for a double extern unsigned char c[sizeof(double)]; // no alignas necessary alignas(float) extern unsigned char c[sizeof(double)]; // error: different alignment in declaration— end example
/* Translation unit A. */
struct foo { int* a; int* b; };
std::atomic<struct foo *> foo_head[10];
int foo_array[10][10];
[[carries_dependency]] struct foo* f(int i) {
return foo_head[i].load(memory_order_consume);
}
int g(int* x, int* y [[carries_dependency]]) {
return kill_dependency(foo_array[*x][*y]);
}
/* Translation unit B. */
[[carries_dependency]] struct foo* f(int i);
int g(int* x, int* y [[carries_dependency]]);
int c = 3;
void h(int i) {
struct foo* p;
p = f(i);
do_something_with(g(&c, p->a));
do_something_with(g(p->a, &c));
}
( string-literal )
struct [[nodiscard]] error_info { /* ... */ };
error_info enable_missile_safety_mode();
void launch_missiles();
void test_missiles() {
enable_missile_safety_mode(); // warning encouraged
launch_missiles();
}
error_info &foo();
void f() { foo(); } // warning not encouraged: not a nodiscard call, because neither
// the (reference) return type nor the function is declared nodiscard
— end example