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 标准会破坏与现有代码的向后兼容性,而且不太可能发生。