statement: labeled-statement attribute-specifier-seq expression-statement attribute-specifier-seq compound-statement attribute-specifier-seq selection-statement attribute-specifier-seq iteration-statement attribute-specifier-seq jump-statement declaration-statement attribute-specifier-seq try-block init-statement: expression-statement simple-declaration condition: expression attribute-specifier-seq decl-specifier-seq declarator brace-or-equal-initializerThe optional attribute-specifier-seq appertains to the respective statement.
if (int x = f()) {
int x; // ill-formed, redeclaration of x
}
else {
int x; // ill-formed, redeclaration of x
}labeled-statement: attribute-specifier-seq identifier : statement attribute-specifier-seq case constant-expression : statement attribute-specifier-seq default : statementThe optional attribute-specifier-seq appertains to the label.
compound-statement: { statement-seq }
statement-seq: statement statement-seq statementA compound statement defines a block scope ([basic.scope]).
selection-statement: if constexpr ( init-statement condition ) statement if constexpr ( init-statement condition ) statement else statement switch ( init-statement condition ) statementSee [dcl.meaning] for the optional attribute-specifier-seq in a condition.
template<typename T, typename ... Rest> void g(T&& p, Rest&& ...rs) {
// ... handle p
if constexpr (sizeof...(rs) > 0)
g(rs...); // never instantiated with an empty argument list
}
extern int x; // no definition of x required
int f() {
if constexpr (true)
return 0;
else if (x)
return x;
else
return -x;
}if constexpr ( init-statement condition ) statementis equivalent to
{ init-statement if constexpr ( condition ) statement }and an if statement of the form
if constexpr ( init-statement condition ) statement else statementis equivalent to
{ init-statement if constexpr ( condition ) statement else statement }except that names declared in the init-statement are in the same declarative region as those declared in the condition.
case constant-expression :where the constant-expression shall be a converted constant expression ([expr.const]) of the adjusted type of the switch condition.
switch ( init-statement condition ) statementis equivalent to
{ init-statement switch ( condition ) statement }except that names declared in the init-statement are in the same declarative region as those declared in the condition.
iteration-statement: while ( condition ) statement do statement while ( expression ) ; for ( init-statement condition ; expression ) statement for ( for-range-declaration : for-range-initializer ) statement
for-range-declaration: attribute-specifier-seq decl-specifier-seq declarator attribute-specifier-seq decl-specifier-seq ref-qualifier [ identifier-list ]
for-range-initializer: expr-or-braced-init-listSee [dcl.meaning] for the optional attribute-specifier-seq in a for-range-declaration.
void f() {
for (int i = 0; i < 10; ++i)
int i = 0; // error: redeclaration
for (int i : { 1, 2, 3 })
int i = 1; // error: redeclaration
}
while (T t = x) statement
label:
{ // start of condition scope
T t = x;
if (t) {
statement
goto label;
}
} // end of condition scope
The variable created in a condition is destroyed and created with each
iteration of the loop.
struct A {
int val;
A(int i) : val(i) { }
~A() { }
operator bool() { return val != 0; }
};
int i = 1;
while (A a = i) {
// ...
i = 0;
}for ( init-statement condition ; expression ) statementis equivalent to
{ init-statement while ( condition ) { statement expression ; } }except that names declared in the init-statement are in the same declarative region as those declared in the condition, and except that a continue in statement (not enclosed in another iteration statement) will execute expression before re-evaluating condition.
int i = 42;
int a[10];
for (int i = 0; i < 10; i++)
a[i] = i;
int j = i; // j = 42
for ( for-range-declaration : for-range-initializer ) statementis equivalent to
{ auto &&__range = for-range-initializer ; auto __begin = begin-expr ; auto __end = end-expr ; for ( ; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } }where
while (foo) {
{
// ...
}
contin: ;
}
do {
{
// ...
}
contin: ;
} while (foo);
for (;;) {
{
// ...
}
contin: ;
}declaration-statement: block-declarationIf an identifier introduced by a declaration was previously declared in an outer block, the outer declaration is hidden for the remainder of the block, after which it resumes its force.
void f() {
// ...
goto lx; // ill-formed: jump into scope of a
// ...
ly:
X a = 1;
// ...
lx:
goto ly; // OK, jump implies destructor call for a followed by
// construction again immediately following label ly
}
int foo(int i) {
static int s = foo(2*i); // recursive call - undefined
return i+1;
}T(a)->m = 7; // expression-statement T(a)++; // expression-statement T(a,5)<<c; // expression-statement T(*d)(int); // declaration T(e)[5]; // declaration T(f) = { 1, 2 }; // declaration T(*g)(double(3)); // declaration
class T {
// ...
public:
T();
T(int);
T(int, int);
};
T(a); // declaration
T(*b)(); // declaration
T(c)=7; // declaration
T(d),e,f=3; // declaration
extern int h;
T(g)(h,2); // declaration
struct T1 {
T1 operator()(int x) { return T1(x); }
int operator=(int x) { return x; }
T1(int) { }
};
struct T2 { T2(int){ } };
int a, (*(*b)(T2))(int), c, d;
void f() {
// disambiguation requires this to be parsed as a declaration:
T1(a) = 3,
T2(4), // T2 will be declared as a variable of type T1, but this will not
(*(*b)(T2(c)))(int(d)); // allow the last part of the declaration to parse properly,
// since it depends on T2 being a type-name
}