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 exampletypedef 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 examplevoid 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 example
void 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:
// ...
};