attribute-specifier-seq: attribute-specifier-seq attribute-specifier
attribute-specifier: [ [ attribute-using-prefix attribute-list ] ] contract-attribute-specifier 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)); }
contract-attribute-specifier: [ [ expects contract-level : conditional-expression ] ] [ [ ensures contract-level identifier : conditional-expression ] ] [ [ assert contract-level : conditional-expression ] ]
contract-level: default audit axiom
int f(char * c) [[ensures res: res > 0 && c != nullptr]]; int g(double * p) [[ensures audit res: res != 0 && p != nullptr && *p <= 0.0]];— end example
void push(int x, queue & q) [[expects: !q.full()]] [[ensures: !q.empty()]] { /* ... */ [[assert: q.is_valid()]]; /* ... */ } int min = -42; constexpr int max = 42; constexpr int g(int x) [[expects: min <= x]] // error [[expects: x < max]] // OK { /* ... */ [[assert: 2*x < max]]; [[assert: ++min > 0]]; // undefined behavior /* ... */ }— end example
typedef int (*fpt)() [[ensures r: r != 0]]; // error: contract condition not on a function declaration int g(int x) [[expects: x >= 0]] [[ensures r: r > x]] { return x+1; } int (*pf)(int) = g; // OK int x = pf(5); // contract conditions of g are checked— end example
class X { public: int v() const; void f() [[expects: x > 0]]; // error: x is private void g() [[expects: v() > 0]]; // OK friend void r(int z) [[expects: z > 0]]; // OK friend void s(int z) [[expects: z > x]]; // error: x is private protected: int w(); void h() [[expects: x > 0]]; // error: x is private void i() [[ensures: y > 0]]; // OK void j() [[ensures: w() > 0]]; // OK int y; private: void k() [[expects: x > 0]]; // OK int x; }; class Y : public X { public: void a() [[expects: v() > 0]]; // OK void b() [[ensures: w() > 0]]; // error: w is protected protected: void c() [[expects: w() > 0]]; // OK };— end example
void f(int * p) [[expects: p != nullptr]] // #1 [[ensures: *p == 1]] // #3 [[expects: *p == 0]] // #2 { *p = 1; }— end example
int f(int x) [[ensures r: r == x]] { return ++x; // undefined behavior } int g(int * p) [[ensures r: p != nullptr]] { *p = 42; // OK, p is not modified } int h(int x) [[ensures r: r == x]] { potentially_modify(x); // undefined behavior if x is modified return x; }— end example
int z;
bool is_prime(int k);
void f(int x)
[[expects: x > 0]]
[[expects audit: is_prime(x)]]
[[ensures: z > 10]]
{
/* ... */
}
— end examplevoid f(int x) noexcept [[expects: x > 0]]; void g() { f(0); // std::terminate() if violation handler throws /* ... */ }— end example
void f(int x) [[expects: x > 0]]; void g() { f(0); // std::terminate() after handler if continuation mode is off; // proceeds after handler if continuation mode is on /* ... */ }— end example
( string-literal )
void g(int); int f(int n) { if (n > 5) [[unlikely]] { // n > 5 is considered to be arbitrarily unlikely g(0); return n * 2 + 1; } switch (n) { case 1: g(1); [[fallthrough]]; [[likely]] case 2: // n == 2 is considered to be arbitrarily more g(2); // likely than any other value of n break; } return 3; }— end example
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
template<typename Key, typename Value, typename Hash, typename Pred, typename Allocator> class hash_map { [[no_unique_address]] Hash hasher; [[no_unique_address]] Pred pred; [[no_unique_address]] Allocator alloc; Bucket *buckets; // ... public: // ... };