Как избежать предупреждения MSVC C4701: потенциально неинициализированная локальная переменная - PullRequest
0 голосов
/ 22 октября 2018

У меня есть кроссплатформенный код, который я сократил до следующего:

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, я сообщил об этом в Microsoft , возможно, они исправят это в будущем компиляторе.Это сложная проблема, и они в хорошей компании

Ответы [ 3 ]

0 голосов
/ 22 октября 2018

Компилятор не видит, что 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;
        }
    }
}
0 голосов
/ 22 октября 2018

Лично я бы инициализировал указатель на NULL и продолжил бы со своей жизнью.

Если вы не хотите изменять уровни предупреждений или вставляете предупреждения прагмы вподавить его просто там, вы можете изменить его глобально в свойствах.

(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, а затем снова скопировать их для собственного кода.

0 голосов
/ 22 октября 2018

Одна проблема заключается в том, что 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;

чтобы избавиться от предупреждения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...