变量在C ++中命名歧义

时间:2016-05-31 09:23:20

标签: c++ ambiguous

我对这种情况感到有点困惑:

#include <iostream>

void function(int origin)
{
    if (origin < 0)
    {
        double origin = 0.3;

        std::cout << origin << std::endl;
    }
}

int main()
{
    function(-4);
}

在v120 ToolSet下使用VS2013编译并成功运行的地方。是不是错了C ++? '因为做同样但只是在函数的开头它给出了编译时错误。

4 个答案:

答案 0 :(得分:2)

根据C ++标准第3.3.3.1节

,这是合法的
  

块中声明的名称是该块的本地名称;它有块范围。它的潜在范围从其声明点开始,并在其块结束时结束。在块作用域中声明的变量是局部变量。

此类重新声明会隐藏origin参数。

  

因为做同样的事情但只是在函数的开头它会产生编译时错误。

您收到错误,因为C ++标准明确禁止在3.3.3.2节中重新声明:

  

参数名称不得在函数定义的最外层块中重新声明,也不得在与function-try-block相关联的任何处理程序的最外层块中重新声明。

这种排除的原因是函数参数是函数外部作用域的本地参数,因此重新声明而没有另一层大括号会在同一作用域中引入重复的标识符。

答案 1 :(得分:1)

  

C ++不是错吗?

没有。重新声明标识符是完全合法的,只要它在不同的范围内。在这种情况下,范围是if语句的then-body。

这不是模棱两可的。将使用最近的声明。

答案 2 :(得分:1)

不,没错。根据标准,这是一种完全有效的行为。

void function(int origin)
{
    if (origin < 0) // scope of the first 'origin'
    {
        double origin = 0.3; // scope of the second 'origin' begins
                             // scope of the first 'origin' is interrupted

        std::cout << origin << std::endl;
    } //block ends, scope of the second 'origin' ends
      //scope of the first 'origin' resumes
}

正如tupe_cat所说,如果他们的范围变化,重新声明它总是有效的。在这种情况下,属于内部范围的变量将超越外部范围。

答案 3 :(得分:1)

我不介意这种C ++行为。当然,它可以导致你已经证明的错误/疏忽。但是你可以在C ++中做到这一点

for (int i = 0; i < 4; ++i) {
    for (int i = 0; i < 5; ++i) {
        cout << i;
    }
    cout << i;
}
cout << endl;
for (int i = 0; i < 4; ++i) {
    for (int j = 0; j < 5; ++j) {
        cout << j;
    }
    cout << i;
}

并且结果完全相同,因为i在内部for循环的范围内被重新定义为另一个变量。

在C#等其他语言中你不能这样做。它会告诉您已尝试在内部范围中重新声明同名变量。

我发现这种过度保护。当我使用循环剪切和粘贴代码时,必须重新声明i(我们都倾向于将其用作循环变量)为i1i2等等,这令人恼火。我总是想念一个,使用剪切和粘贴代码,所以我在arr[i]循环中使用i3,当我的意思是arr[i3](哎呀)。

在生产代码中,我同意防御性编码意味着你应该在同一个函数中为循环变量使用不同的名称。

但是,当您进行实验时,能够在嵌套for循环中重用变量名称是很好的。 C ++为您提供了这种选择。