18

VC++ for 变量作用域的 “bug”

 4 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzU4OTQyODI0Mw%3D%3D&%3Bmid=2247483664&%3Bidx=1&%3Bsn=59e31827963b60e759405a41171baaa9&%3Bchksm=fdcce26ccabb6b7a480dbfea7255409d4b6e4969d5f5b80628979e292caf7e0b4d916584334e&%3Btoken=824700414&%3Blang=zh_CN
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

工作中一不小心掉进了历史的“坑”里,说起渊源,这还得从1998年说起。

VC 6.0是微软98年出品的一款经典的C/C++ IDE,想必很多人用过,我在大学时C++课程的上机软件就是这老兄。那一年还出了C++98标准。按照微软以前的作风,其对标准的支持是相对滞后的,所以VC 6.0并不完全兼容C++98标准。这篇文章说的就是其中一个不兼容的情况—for结构变量作用域的差异。

C++语言规范定义:

If the for-init-statement is a declaration, the scope of the name(s) declared extends to the end of the for-statement .

即,for右边括号内初始化的变量的作用域在for语句内,变量超出for语句的花括号就被会被销毁。而VC 6.0允许变量继续“生存”。如下代码,在VC 6.0可以编译,在现代编译器编译不通过,会报“ 未声明的标识符 ”之类的错误:

#include <iostream>int main() {    int pids[] = {1, 2, 3, 4, 5};    for (int i = 0; i < sizeof(pids) / sizeof(int); i++) {        if (pids[i] == 2) {
            std::cout << "found 2" << std::endl;
        }
    }

    std::cout << i << std::endl;    return 0;
}

后续出品的Visual Studio对其进行了修复,默认情况遵循C++标准,但为了兼容以前的代码,在产品里提供了对其行为的配置项:

VS 2003的配置:

NjeQbab.jpg!web

VS 2010的配置:

NjeQbab.jpg!web

问题就出在这个配置项上。公司项目默认兼容VC6 的代码,所以上面的配置是 NO ,而恰巧我写出了类似上面的代码。故有问题的代码跳过了编译器的检查,导致了运行时的逻辑错误。

建议:

!!没有特殊原因,配置选 Yes ,严格遵循C++标准。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK