在循环中重新声明for循环变量时出错

Ayu*_*ngh 24 c c++ for-loop

考虑一下C程序的片段:

for(int i = 0; i < 5; i++)
{
    int i = 10;  // <- Note the local variable

    printf("%d", i); 
}    
Run Code Online (Sandbox Code Playgroud)

它编译没有任何错误,并在执行时,它提供以下输出:

1010101010
Run Code Online (Sandbox Code Playgroud)

但是如果我在C++中编写类似的循环:

for(int i = 0; i < 5; i++)
{
     int i = 10;

     std::cout << i; 
}
Run Code Online (Sandbox Code Playgroud)

编译失败,出现此错误:

prog.cc:7:13: error: redeclaration of 'int i'  
     int i = 10;  
         ^  
prog.cc:5:13: note: 'int i' previously declared here  
     for(int i = 0; i < 5; i++)  
             ^   
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

das*_*ght 26

这是因为C和C++语言在嵌套在for循环中的作用域中重新声明变量的规则不同:

  • C++放入i循环体的范围,所以第二个int i = 10是重新声明,这是禁止的
  • C允许在for循环内的范围内重新声明; 最里面的变量"胜利"

这是一个正在运行的C程序的演示,以及一个无法编译C++程序.

在正文中打开嵌套作用域修复了编译错误(演示):

for (int i =0 ; i != 5 ; i++) {
    {
        int i = 10;
        cout << i << endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在ifor标题中并且int i = 10位于不同的范围内,因此允许程序运行.

  • @迅速; 这根本不是真的. (6认同)

hac*_*cks 21

与C不同,C++有规则,
C++ 11-§6.5.3/ 1:

for声明

for ( for-init-statement conditionopt ; expressionopt ) statement 

相当于

{
    for-init-statement 
    while ( condition ) {
        statement 
        expression ;
    } 
}
Run Code Online (Sandbox Code Playgroud)

除了在for-init-statement中声明的名称与条件[...]中 声明的名称相同的声明区域

这意味着的是,范围for-init-statementstatement是相同的*和下面的代码将导致错误

for(int i = 0; i < 5; i++){
     int i = 10;    // Invalid. 
     // ...
}
Run Code Online (Sandbox Code Playgroud)

在C,
C11-§6.8.5/ 5中:

迭代语句是一个块,其范围是其封闭块范围的严格子集.循环体也是一个块,其范围是迭代语句范围的严格子集.

因此,statement它有自己的范围,上面的代码是有效的和等价的

for(int i = 0; i < 5; i++){
    {
         int i = 10;    // Valid. 
         // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

建议阅读:n3337:6.5.1 while语句/ p(2).相同的参考资料可以在第9.5.1节和第9.5.3节中的c ++ 17 draft(n4659)中找到.