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

Posted

技术标签:

【中文标题】这是 MSVC++ 2017 更新 3 中的编译器错误吗【英文标题】:Is this a compiler bug in MSVC++ 2017 update 3 【发布时间】:2018-03-08 08:11:01 【问题描述】:
#include <vector>

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

int main()

    void* p;
    while (foo() != foo() && (p = 0, true))
    
        bar(p);
    
    return 0;

导致错误:

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

【问题讨论】:

赞成,但你能举一个稍微不那么复杂、更有动力的例子吗? 你会期待什么? 我看不到在初始化之前如何访问p 的值。此外,在编译器资源管理器上的 MSVC 版本上,代码只是编译没有错误link。当然是编译器错误。 @M.M 它当然应该编译,但它没有。 不明白为什么需要这个while (foo() != foo() &amp;&amp; (p = 0, true)),尤其是(p = 0, true) 部分?测试“技巧”并降低程序的可读性?为什么不用!(p = 0) 而不是(p = 0, true) 【参考方案1】:

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

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

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

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

所以这是一个工程权衡。你可以报告这个错误,但如果你这样做了,我建议你提供一个更引人注目的真实世界的惯用代码示例,以支持使分析更复杂。你确定你不能重构你的原始代码,让它更容易被编译器接受,同时对人类来说更易读吗?

【讨论】:

我收回了。这是一个错误,因为关闭所有警告并不能挽救这一天。现在这是一个硬错误。 1&gt;c:\users\dave\documents\vc++ 2017\projects\scratch\scratch.cpp(81): error C4703: potentially uninitialized local pointer variable 'p' used 奇怪的事情正在发生。 “错误”生成较晚 - 可能是在链接时,或者可能是在整个程序优化期间。 平。这是定义。破碎的。 C4703 报告为错误,而不是警告。它不能被禁用。我不知道这是否是新行为。 @JiveDadson 嗯,这很有趣。这个警告并不新鲜。它一直记录在VS2012。最好的猜测是他们重写了分析作为编译器重构的一部分并且搞砸了。在这种情况下,您绝对应该报告错误。 我开始做,但我觉得让 Jesse 做会更容易。【参考方案2】:

我用 VC++2017 Preview 做了一些试验。

这绝对是一个错误错误。它使得编译和链接可能正确的代码变得不可能,尽管有异味。

可以接受警告。 (请参阅@SebastianRedl 的回答。)但在最新和最伟大的 VC++2017 中,它被视为错误,而不是警告,即使关闭了警告,并且“将警告视为错误”设置为否。奇怪的事情正在发生. “错误”被延迟抛出 - 在它说“生成代码”之后。我猜想,这只是一个猜测,“生成代码”传递正在进行全局分析,以确定是否可以进行未初始化的访问,并且它弄错了。即使那样,您也应该能够禁用该错误,IMO。

我不知道这是否是新行为。阅读塞巴斯蒂安的回答,我想是的。当我收到任何级别的警告时,我总是在代码中修复它,所以我不知道。

Jesse,点击Visual Studio右上角附近的三角旗,举报。

【讨论】:

【参考方案3】:

确定这是一个错误。我试图以所有可能的方式删除它,包括#pragma。实际情况是,这被报告为错误,而不是微软所说的警告。这是微软的一个大错误。这不是警告,而是错误。请不要再重复这是一个警告,因为它不是。 我正在尝试编译一些我不想以任何方式修复其源代码的第三方库,并且应该在正常情况下编译,但它不会在 VS2017 中编译,因为臭名昭著的“错误 C4703:可能未初始化的本地指针变量***已使用”。 有人找到解决方案了吗?

【讨论】:

嗨 Rob,这似乎重复了 Jive Dadson 5 个月前所写的内容。你还不能投票给他的答案(因为你是新来的),但这就是你将来可以表明现有答案是正确的方式。

以上是关于这是 MSVC++ 2017 更新 3 中的编译器错误吗的主要内容,如果未能解决你的问题,请参考以下文章

VS2017搭建QT5编译QT

VS2017搭建QT5编译QT

安装 Qt 5.6.1 MSVC 2015 更新 3

g++ , msvc 2015,2017System: Windows

如何单独提取出MSVC2017编译器并在其他IDE使用

MSVC2015 更新 3 可变参数模板解决方法