如何避免MSVC警告C4701:可能未初始化的局部变量

时间:2018-10-22 17:59:44

标签: c visual-c++

我有一些跨平台的代码,我将其简化为:

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

3 个答案:

答案 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包含文件周围放下警告,然后再次将其重新备份以获取您自己的代码。