根据标准(§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;
}
我似乎不清楚究竟“该陈述的后续条件”究竟是什么。
答案 0 :(得分:2)
突出显示"那" statement表示已定义名称的if
,while
,for
和switch
语句,而不是由条件或迭代控制的子语句。
解释如下:
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。