标准的含义是“该声明的后续条件”?

时间:2015-12-28 16:36:52

标签: c++ language-lawyer

根据标准(§3.3.3/ 4),N4567的标准禁止对以前在条件中声明的名称进行某些类型的重新声明:

  

在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;
}

我似乎不清楚究竟“该陈述的后续条件”究竟是什么。

1 个答案:

答案 0 :(得分:2)

突出显示"那" statement表示已定义名称的ifwhileforswitch语句,而不是由条件或迭代控制的子语句。

解释如下:

  

6.4 / 3:由条件中的声明引入的名称(由decl-specifier-seq或声明者引入的名称)   条件)从声明的范围到结束   由条件控制的子语句。 如果名称是   重新声明在受控制的子语言的最外层   条件,重新声明名称的声明格式不正确。

这就是以下声明有效的原因:

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

编译器将if (int i=20)的声明分析为不是同一if语句的不同条件,而是作为受控子语句。由于i的第二个声明发生在条件中,因此不在被控制的声明的外部块中考虑。

相比之下,以下几乎等效的语句无效,因为它打破了外部块约束:

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

因此,唯一的情况是,您可以拥有&#34; 后续条件 语句&#34;是for语句。标准突出了这种特殊情况,给出了你用更明确的措辞引用的约束的基本原理:

  

6.5.3 / 1:(...)在 for-init-statement 中声明的名称在同一声明区域中 作为条件中声明的那些,

即。在init和条件中声明相同的名称会破坏ODR。