Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the standard mean by "a subsequent condition of that statement"?

The standard as of N4567 forbids some kinds of re-declaration of a name previously declared in a condition as follows—according to the standard(§3.3.3/4):

Names declared in the for-init-statement, the for-range-declaration, and in the condition of if, while, for, and switch statements are local to the if, while, for, or switch statement (including the controlled statement), and shall not be redeclared in a subsequent condition of that statement nor in the outermost block (or, for the if statement, any of the outermost blocks) of the controlled statement; see 6.4.

However, considering the fact that the following code compiles fine,

int main(void) {
    if (int i=10)
        if (int i=20)
            ;
    return 0;
}

it seems unclear to me what exactly "a subsequent condition of that statement" stands for.

like image 971
b1sub Avatar asked Dec 28 '15 16:12

b1sub


1 Answers

The highlighted "that" statement means the if, while, for, and switch statement that has defined the name, and not the substatement controlled by the condition or the iteration.

This is explained in:

6.4/3: A name introduced by a declaration in a condition (either introduced by the decl-specifier-seq or the declara- tor of the condition) is in scope from its point of declaration until the end of the substatements controlled by the condition. If the name is re-declared in the outermost block of a substatement controlled by the condition, the declaration that re-declares the name is ill-formed.

This is why the following statment is valid:

if (int i=10)
    if (int i=20)
        ;

The compiler analyses the declaration of if (int i=20) not as a different condition of the same if-statement, but as a controlled substatement. And as the second declaration of i takes place in the condition, it is not considered in the outer block of the constrolled statement.

By contrast, the following almost equivalent statement is not valid, as it breaks the outer block constraint:

if (int k=10) {
    int k=20;   // <===== ouch ! redefinition in the outerblock 
    if (k)
        cout <<"oops";
}

Hence the only case where you can have a "subsequent condition of that statement" is the for statement. The standandard highlights this special situation, by giving the rationale to the constraint that you've quoted with a clearer wording:

6.5.3/1: (...) names declared in the for-init-statement are in the same declarative-region as those declared in the condition,

i.e. declaring the same name in the init and in the condition would break the ODR.

like image 179
Christophe Avatar answered Nov 09 '22 23:11

Christophe