简体   繁体   中英

How to avoid MSVC warning C4701: potentially uninitialised local variable

I have some cross-platform code, which I've whittled down to this:

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;
}

Compiling this with GCC 7 gives no warnings. Compiling this with MSVC gives two warnings:

$ 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

If n is non-zero, p is initialised. If n is zero, p is not initialised but if (x) and the default zero value of x ensures if (p) is never reached.

How can I tell MSVC to suppress this without either changing compiler warning levels, or initialising p to a dummy value?

FWIW, I reported this to Microsoft , maybe they'll fix it in a future compiler. It's a tricky problem and they're in good company

The compiler doesn't see that if (x) can't be entered unless if (n) is entered, in which case p is assigned to via the function call.

Most compilers don't perform that deep of an analysis (that what static analyzers are for), so it sees a possible code path for p to be read without being initialized.

Perhaps the best way to handle this is to restrict the scope of p to where it is used:

void foo(int n) {
    int x = 0;
    if (n) {
        char *p;
        x = bar(&p);
        if (x && p) {
            return;
        }
    }
}

One problem is that n may be zero (ie due to a call like foo(0); ) so here

    if (n) x = bar(&p);
           ^^^^^^^^^^^ 
           Not executed if n is 0

bar may not be called. In that case p will be uninitialized when used here:

   if (x) if (p) return;
              ^
              Uninitialized if n is 0

as the compiler most likely won't track the value actual value of x .

You could do:

   char *p = NULL;

to get rid of the warning.

Personally, I would initialize the pointer to NULL, and move on with my life.

If you don't want to change the warning levels, or put in warning pragmas to suppress it just there, you can change it globally under properties.

(properties)

(c/c++)

(advanced)

enter 4701;4703 in the "Disable specific warnings" area.

To disable a warning in msvc in-line in the code:

// 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)

In-line warnings are useful to enable you to drop the warnings around the microsoft include files, then jack them back up again for your own code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM