关于c ++:重新定义/阴影局部变量有多严重?


How bad is redefining/shadowing a local variable?

将旧版项目升级到VS2015时,我注意到存在很多错误,例如在函数内部重新定义局部变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
void fun()
{
    int count = applesCount();

    cout <<"Apples cost=" << count * 1.25;

    for (int bag=0; bag<5;bag++)
    {
        int count = orangesCount(bag);

        cout <<"Oranges cost =" << count * 0.75;
    }
}

编译器的错误/警告消息是:

1
declaration of 'count' hides previous local declaration

我知道,对于变量count使用相同的名称显然不是一个好习惯,但是编译器是否也可以将事情弄得一团糟,或者通常情况下它们会比较优美地处理这种情况?

更改和修复变量名是否值得,或者不太可能造成任何损害并且风险很小或没有风险?


I noticed there were a lot of errors where a local variable was redefined inside a function for example.

您不是在这里演示重新定义。您将显示一个可变阴影的示例。

从句法上讲,可变阴影并不是错误。有效且定义明确。但是,如果您打算使用外部作用域中的变量,则可以将其视为逻辑错误。

but can the compiler really mess things up

没有。

阴影的问题在于,可能很难跟踪程序员。对于编译器而言,这是微不足道的。由于阴影变量引起的混乱,您可以在此站点上找到很多问题。

在这个小函数中查找哪个表达式使用哪个变量并不是很困难,但可以想象该函数是数十行以及几个嵌套和顺序的块。如果该函数足够长,以至于您一眼都看不到不同范围内的所有不同定义,则可能会造成误解。

1
declaration of 'count' hides previous local declaration

这是一个有用的编译器警告。您还没有用完名称,为什么不为函数中的所有局部变量指定唯一的名称呢?但是,没有必要将此警告视为错误。这只是提高程序可读性的建议。

在此特定示例中,在内部范围打开之后,您无需在外部范围中使用count,因此您最好对两个计数都重用一个变量。

Is it worth it to change and fix the variable names

取决于您是否更看重短期工作量而不是长期工作量。现在更改代码以使用唯一的描述性局部变量名称是"额外的"工作,但是每次有人以后要理解该程序时,不必要的阴影都会增加思维上的挑战。


阴影变量(即变量)具有完全定义良好的语义,因此编译器不会将其弄乱。它将完全按照已告知的内容进行操作,并具有明确的结果。

问题是(通常是)人类的问题。在读取和修改代码时很容易出错。如果不是很谨慎的话,跟踪被引用的具有给定名称的变量可能很棘手,在您认为自己正在修改一个变量但实际上却在修改另一个变量的地方很容易犯错误。

因此,编译器很好,程序员是问题所在。


恕我直言,不良的编码习惯。难以维护和阅读。

编译器可以区分外部变量和内部变量。

有了一个很好的词汇表(和一个词库),就不需要使用相同的变量名了。


以我的经验,编译器通常会很好地处理此问题。

但是,这绝对不是一个好习惯,除非您有确凿的理由这样做,否则您应该重用旧变量(如果这样做在逻辑上是合理的),或者声明一个[不同名称]新变量。


扎尔

编译器会很好地处理这种情况。在您的示例中,count变量在两个不同的作用域" {}"中定义。由于变量的范围,汇编语言将引用堆栈上的两个不同地址。第一个"计数"可能是堆栈点SP-8,而内部计数可能是SP-4。一旦转换为地址,该名称就无关紧要了。

由于风格原因,我通常不会更改工作代码。如果代码是一团糟,那么您就有可能被破坏。通常,凌乱的代码没有任何好的测试,因此很难知道您是否破坏了它。

如果您需要增强代码,那么一定要整理一下。

-马特