#include <iostream>
int main(){
int b = 2;
if(int a = 0){ // #condition
}else if(b == 2){
int a; //#1
}
}
上面的代码可以是compiled在 gcc 和 clang 中。但是,根据相关规则的说法,这段代码应该是格式错误的。规则是:stmt.stmt#3
A name introduced by a declaration in a condition (either introduced by the decl-specifier-seq or the declarator 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 redeclared in the outermost block of a substatement controlled by the condition, the declaration that redeclares the name is ill-formed.
不是在
else
后面的 if 语句吗?不是由条件控制的子语句? (即,只有 #condition
处的条件被执行为 false
才会执行 else
之后的 if 语句)。那么,为什么在这种子语句的最外层块中重新声明名称的声明可以被视为格式良好的代码?也许在版本
n4659
的规则中对短语“由条件控制的子语句”存在一些争论。不过,这样的想法在最新的草案中显然是清晰的。stmt.stmt#stmt.pre-2
A substatement of a statement is one of the following:
for a selection-statement, any of its statements (but not its init-statement)
这意味着
else
之后的语句是主 if-statement
的子语句,那么接下来的规则说:stmt.stmt#stmt.pre-5
A name introduced in a selection-statement or iteration-statement outside of any substatement is in scope from its point of declaration until the end of the statement's substatements. Such a name cannot be redeclared in the outermost block of any of the substatements
该规则显然表明,我们不能重新声明与这些子语句最外层块中的条件声明相同的名称。那么,我很好奇是我误解了这些规则还是草案中存在一些缺陷?
最佳答案
不。
你错过了 else
引入的块作用域子语句:
[stmt.selected.general/2]
: The substatement in a selection-statement (each substatement, in theelse
form of theif
statement) implicitly defines a block scope ([basic.scope]). If the substatement in a selection-statement is a single statement and not a compound-statement, it is as if it was rewritten to be a compound-statement containing the original substatement. [..]
即你的代码真的是:
#include <iostream>
int main()
{
int b = 2;
if (int a = 0) {
}
else {
if (b == 2) {
int a;
}
}
}
因此,您正在查看的块(由嵌套 if
引入的块)不是所讨论的“最外层”块。所以,虽然 a
在该块的范围内,它可以被隐藏。这确实意味着 you can't declare an
a
inside a "naked" else
,即以下格式不正确:#include <iostream>
int main()
{
int b = 2;
if (int a = 0) {
}
else {
int a;
}
}
/*
prog.cpp: In function ‘int main()’:
prog.cpp:9:9: error: redeclaration of ‘int a’
int a;
^
prog.cpp:6:11: note: ‘int a’ previously declared here
if (int a = 0) {
*/
关于c++ - 在子语句的最外层 block 中重新声明的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64707811/