我有一些跨平台的代码,我将其简化为:
int bar(char **p) {
*p = "hello";
return 1;
}
void foo(int n) {
int x = 0;
char *p;
if (n) x = bar(&p);
if (x) if (p) return;
}
使用GCC 7进行编译不会产生任何警告。使用MSVC进行编译会给出两个警告:
$ gcc -Wall -Wextra -c foo.c
$ cl /Wall /c foo.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.15.26730 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
foo.c
c:\cygwin64\home\kyz\foo.c(9) : warning C4701: potentially uninitialized local variable 'p' used
c:\cygwin64\home\kyz\foo.c(9) : warning C4703: potentially uninitialized local pointer variable 'p' used
如果n
不为零,则初始化p。如果n
为零,则p
不会初始化,而是if (x)
且x
的默认零值可确保从未达到if (p)
。
我如何告诉MSVC在不更改编译器警告级别或将p
初始化为虚拟值的情况下进行抑制?
FWIW,我reported this to Microsoft,也许他们会在以后的编译器中修复它。这是一个棘手的问题,they're in good company
答案 0 :(得分:3)
除非输入if (x)
,否则编译器不会看到无法输入if (n)
,在这种情况下,通过函数调用将p
分配给了p
。
大多数编译器没有进行那么深入的分析(即静态分析器的用途),因此它看到了p
可能被读取而无需初始化的代码路径。
也许最好的处理方法是将void foo(int n) {
int x = 0;
if (n) {
char *p;
x = bar(&p);
if (x && p) {
return;
}
}
}
的范围限制在使用范围:
{{1}}
答案 1 :(得分:2)
一个问题是n
可能为零(即由于诸如foo(0);
之类的调用),所以在这里
if (n) x = bar(&p);
^^^^^^^^^^^
Not executed if n is 0
bar
可能不会被调用。在这种情况下,p
在此处使用时将未初始化:
if (x) if (p) return;
^
Uninitialized if n is 0
因为编译器很可能不会跟踪x
的实际值。
您可以这样做:
char *p = NULL;
摆脱警告。
答案 2 :(得分:1)
我个人将指针初始化为NULL,然后继续我的生活。
如果您不想更改警告级别,或者不想在其中添加warning pragmas来抑制它,则可以在属性下全局更改它。
(properties)
(c/c++)
(advanced)
enter 4701;4703 in the "Disable specific warnings" area.
要在代码中的嵌入式msvc中禁用警告:
// Save warning levels, and drop it to level 3
#pragma warning (push, 3)
// turn two warnings off
#pragma warning (disable : 4701 4703)
// screwy code goes here
// restore original warning levels.
#pragma warning (pop)
行内警告非常有用,可以使您在Microsoft包含文件周围放下警告,然后再次将其重新备份以获取您自己的代码。