#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'使用
答案 0 :(得分:6)
这是一种错误,但对于你编写的代码非常典型。
首先,这不是错误,而是一个警告。 C4703是4级警告(意味着默认情况下甚至没有启用)。因此,为了将其报告为错误(从而中断编译),传递了编译器参数或编译指示以启用此警告并将其转换为错误(/W4
和/Werror
最可能是我想)。
然后在编译器中进行权衡。数据流分析应该有多复杂来确定变量是否实际上未初始化?它应该是程序间的吗?它越复杂,编译器就越慢(并且由于停止问题,问题可能是不可判定的)。它越简单,你得到的误报就越多,因为保证初始化的条件太复杂,编译器无法理解。
在这种情况下,我怀疑编译器的分析工作如下:对p
的赋值是在条件后面(只有在foo() != foo()
时才会发生)。 p
的用法也在条件之后(只有当复数和表达式为真时才会发生)。编译器无法在这些条件之间建立关系(分析不够复杂,无法实现foo() != foo()
是整个while循环条件为真的前提条件)。因此,编译器错误地认为访问可能在没有事先初始化的情况下发生并发出警告。
所以这是一项工程权衡。您可以报告错误,但如果您这样做,我建议您提供一个更具吸引力的现实世界的惯用代码示例,以支持使分析更复杂。您确定不能重构原始代码以使其更易于编辑,并且同时对人类更具可读性吗?
答案 1 :(得分:4)
我做了一些VC ++ 2017预览试验。
这肯定是 错误 错误。这使得编译和链接可能正确的代码变得不可能,但是很有趣。
警告是可以接受的。 (参见@SebastianRedl回答。)但是在最新最好的VC ++ 2017中,它被视为错误,而不是警告,即使关闭警告,并将“将警告视为错误”设置为否。发生了奇怪的事情。 “错误”被推迟了 - 在它说“生成代码”之后。我猜,并且只是猜测,“生成代码”传递正在进行全局分析,以确定是否可以进行未初始化的访问,并且它是错误的。即使这样,你也应该能够禁用错误IMO。
我不知道这是否是新行为。读塞巴斯蒂安的回答,我认为是。当我在任何级别发出任何警告时,我总是在代码中修复它,所以我不知道。
Jesse,单击Visual Studio右上角附近的三角形标记,然后进行报告。
答案 2 :(得分:1)
确定这是一个错误。我试图以所有可能的方式将其删除,包括#pragma。真正的事实是,这被报告为错误,而不是微软所说的警告。这是微软的一个大错误。这不是警告,而是错误。请,不要再重复一次,这是一个警告,因为不是。 我正在做的是尝试编译一些第三方库,这些源我不希望以任何方式进行修复,并且在正常情况下应该进行编译,但是在VS2017中不编译,因为臭名昭著的“错误C4703:可能未初始化的本地指针变量***使用”。 有人找到了解决方案吗?