C++ 中 `for` 循环的作用域规则与 C 中的不同?
Scope rules of `for` loop different in C++ than in C?
我注意到 for
循环的范围规则对于 C 和 C++ 是不同的。
例如,下面的代码在C编译器中是合法的,但在C++编译器中是不合法的。
for (int i = 0; i < 10; ++i) {
int i = 5;
}
以上代码在C中有效,但在C++中给出重定义错误。
我的猜测是 C 编译器将循环视为循环内有另一个作用域,如下所示。
for (int i = 0; i < 10; ++i) {
{
int i = 5;
}
}
为什么 C 编译器允许在循环范围内定义第二个同名变量?这样做有什么特别的原因或优势吗?
就标准而言,for
循环作用域在 C 和 C++ 中的定义确实不同。在 C 中,它们的定义如下:
6.8.5.3 The for statement
The statement
for ( clause-1 ; expression-2 ; expression-3 ) statement
behaves as follows: ...
没有具体提及 statement
中变量声明的限制。循环的顶级描述(标准中的“迭代语句”)指定:
An iteration statement is a block whose scope is a strict subset of
the scope of its enclosing block. The loop body is also a block whose
scope is a strict subset of the scope of the iteration statement.
正如您在问题中暗示的那样,代码如下:
for (int i = 0; i < 10; ++i)
int i = 5;
未声明新块的地方(注意重新声明周围缺失的 { }
)- 不是有效代码。
而在 C++ 中,对循环变量的重新声明有具体的参考:
8.6 Iteration statements specify looping ... If a name introduced in an
init-statement or for-range-declaration is redeclared in the outermost
block of the substatement, the program is ill-formed.
因为它与基本原理有关 - 可能 C++ 只是添加限制作为对语言语义的改进,确实以这种方式重新声明变量是 通常 一个错误。
可以说,此限制在 C 中也适用 - 但将此限制添加到 C 标准会破坏与现有代码的向后兼容性,而且不太可能发生。
我注意到 for
循环的范围规则对于 C 和 C++ 是不同的。
例如,下面的代码在C编译器中是合法的,但在C++编译器中是不合法的。
for (int i = 0; i < 10; ++i) {
int i = 5;
}
以上代码在C中有效,但在C++中给出重定义错误。
我的猜测是 C 编译器将循环视为循环内有另一个作用域,如下所示。
for (int i = 0; i < 10; ++i) {
{
int i = 5;
}
}
为什么 C 编译器允许在循环范围内定义第二个同名变量?这样做有什么特别的原因或优势吗?
就标准而言,for
循环作用域在 C 和 C++ 中的定义确实不同。在 C 中,它们的定义如下:
6.8.5.3 The for statement
The statement
for ( clause-1 ; expression-2 ; expression-3 ) statement
behaves as follows: ...
没有具体提及 statement
中变量声明的限制。循环的顶级描述(标准中的“迭代语句”)指定:
An iteration statement is a block whose scope is a strict subset of the scope of its enclosing block. The loop body is also a block whose scope is a strict subset of the scope of the iteration statement.
正如您在问题中暗示的那样,代码如下:
for (int i = 0; i < 10; ++i)
int i = 5;
未声明新块的地方(注意重新声明周围缺失的 { }
)- 不是有效代码。
而在 C++ 中,对循环变量的重新声明有具体的参考:
8.6 Iteration statements specify looping ... If a name introduced in an init-statement or for-range-declaration is redeclared in the outermost block of the substatement, the program is ill-formed.
因为它与基本原理有关 - 可能 C++ 只是添加限制作为对语言语义的改进,确实以这种方式重新声明变量是 通常 一个错误。
可以说,此限制在 C 中也适用 - 但将此限制添加到 C 标准会破坏与现有代码的向后兼容性,而且不太可能发生。