Подтвердить что ты не робот

Что означает стандарт под "последующим условием этого утверждения"?

Стандарт по N4567 запрещает некоторые виды повторного объявления имени, ранее объявленного в условии следующим образом - в соответствии со стандартом (§3.3.3/4):

Имена, объявленные в for-init-statement, for-range-declaration и в условии if, while, for и switch, являются локальными для оператора if, while, for или switch (включая управляемый оператор) и не должен быть повторно объявлен в последующем условии этого оператора, а также в самом удаленном блоке (или для оператора if) любого из внешних блоков управляемой инструкции; см. 6.4.

Однако, учитывая тот факт, что следующий код компилируется нормально,

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

мне кажется непонятным, что именно означает "последующее условие этого утверждения".

4b9b3361

Ответ 1

Выделенный оператор "that" означает оператор if, while, for и switch, который определил имя, а не подсистему, контролируемую условием или итерацией.

Это объясняется в:

6.4/3: Имя, введенное декларацией в условии (либо введенное decl-specifier-seq, либо декларатором условие) находится в пределах от точки объявления до конца подстанции, контролируемые условием. Если имя повторно заявлен в самом удаленном блоке подстанции, контролируемой условие, декларация, которая повторно объявляет имя, плохо сформирована.

Вот почему допустимо следующее условие:

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

Компилятор анализирует объявление if (int i=20) не как другое условие одного и того же оператора if, а как контролируемое подкрепление. И поскольку второе объявление я имеет место в условии, оно не рассматривается во внешнем блоке сконфигурированного оператора.

В отличие от этого, следующий почти эквивалентный оператор недействителен, так как он нарушает ограничение внешнего блока:

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

Следовательно, единственный случай, когда вы можете иметь следующее условие , которое - это оператор for. Standandard подчеркивает эту особую ситуацию, давая обоснование ограничениям, которые вы цитировали с более ясной формулировкой:

6.5.3/1: (...) имена, объявленные в for-init-statement, в той же декларативной области, что и те, которые указаны в условии,

то есть. объявление одного и того же имени в init и в состоянии приведет к поломке ODR.