这是MSVC++ 2017更新3中的编译器错误

Jes*_*per 4 c++ visual-studio compiler-bug

#include <vector>

std::vector<int>::iterator foo();
void bar(void*) {}

int main()
{
    void* p;
    while (foo() != foo() && (p = 0, true))
    {
        bar(p);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果有误:

c:\ users\jessepepper\source\repos\testcode\consoleapplication1\consoleapplication1.cpp(15):错误C4703:使用了未初始化的本地指针变量'p'

Seb*_*edl 6

这是一种错误,但对于您编写的代码类型来说非常典型.

首先,这不是一个错误,这是一个警告.C4703是4级警告(意味着默认情况下甚至没有启用).因此,为了得到它报告为错误(因而中断编译),编译参数或编译指示传递给启用此警告,并把它变成一个错误(/W4/Werror最有可能,我认为).

然后在编译器中进行权衡.数据流分析应该有多复杂来确定变量是否实际上未初始化?它应该是程序间的吗?它越复杂,编译器就越慢(并且由于停止问题,问题可能是不可判定的).它越简单,你得到的误报就越多,因为保证初始化的条件太复杂,编译器无法理解.

在这种情况下,我怀疑编译器的分析工作如下:赋值p是在条件后面(只有在发生时foo() != foo()).用法p也在条件之后(只有当复数和表达式为真时才会发生).编译器无法在这些条件之间建立关系(分析不够复杂,无法实现foo() != foo()整个while循环条件为真的前提条件).因此,编译器错误地认为访问可能在没有事先初始化的情况下发生并发出警告.

所以这是一个工程权衡.您可以报告错误,但如果您这样做,我建议您提供一个更具吸引力的现实世界的惯用代码示例,以支持使分析更复杂.您确定无法重构原始代码以使其更易于编辑,并且同时对人类更具可读性吗?