C - компиляция с -Wall не предупреждает о неинициализированных переменных

У меня есть пример ошибочной программы, которая должна выдавать ровно одно предупреждение о неинициализированной переменной, но когда я ее компилирую, gcc не выдает никаких предупреждений.

Вот код:

#include <stdio.h>

int main()
{
    int foo;

    printf("I am a number: %d \n", foo);

    return 0;
}

Вот что я запускаю: cc -Wall testcase.c -o testcase

И я не получаю обратной связи. Насколько я знаю, это должно произвести:

testcase.c: In function 'main': 
testcase.c:7: warning: 'foo' is used uninitialized in this function

По-видимому, он правильно предупреждает Зеда Шоу в подобном примере. в своем руководстве по C). Это пример, который я впервые попробовал и заметил, что он работает не так, как ожидалось.

Любые идеи?

ИЗМЕНИТЬ:

Версия gcc:

i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)

person Nick Knowlson    schedule 10.05.2012    source источник
comment
Используйте Clang, покончим с этим ;-).   -  person rubenvb    schedule 11.05.2012
comment
rubenvb, это сработало, опубликуйте это как ответ, и я приму его!   -  person Nick Knowlson    schedule 30.05.2012


Ответы (4)


Используйте Clang, покончим с этим. Похоже на ошибку в GCC, потому что Clang предупреждает, как и должно быть.

person rubenvb    schedule 30.05.2012
comment
Дополнительная информация: обновление gcc также было вариантом, но использование clang оказалось для меня лучшим выбором. - person Nick Knowlson; 30.05.2012

Вы компилируете с включенной оптимизацией? Вот что написано на моей man gcc странице:

  -Wuninitialized
       Warn if an automatic variable is used without first being
       initialized or if a variable may be clobbered by a "setjmp" call.

      These warnings are possible only in optimizing compilation, because
       they require data flow information that is computed only when
       optimizing.  If you do not specify -O, you will not get these
       warnings. Instead, GCC will issue a warning about -Wuninitialized
       requiring -O.

Моя версия gcc:

i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)

На самом деле, я только что попробовал это на gcc 4.4.5, и я действительно получаю предупреждение без использования -O. Так что это зависит от версии вашего компилятора.

person Greg Hewgill    schedule 10.05.2012
comment
Спасибо за ответ. Я пробовал cc -Wall -O testcase.c -o testcase и cc -Wuninitialized -O testcase.c -o testcase без разницы. Также gcc не выдает предупреждение о том, что -Wuninitialized требует -O. - person Nick Knowlson; 11.05.2012
comment
@NickKnowlson: Похоже, что в gcc 4.2 -Wall не подразумевает -Wuninitialized. Кроме того, эта версия gcc не может определить, что foo на самом деле не используется. - person Greg Hewgill; 11.05.2012
comment
gcc.gnu.org/onlinedocs/ gcc-4.2.1/gcc/ Документы говорят об обратном, похоже. эта версия gcc, похоже, не может обнаружить, что foo на самом деле не используется. Итак, тогда это настоящий ответ? Эта версия не может обнаружить, что foo по какой-то причине не инициализирован? Я попробую еще несколько сценариев и посмотрю, смогу ли я создать какие-либо условия там, где это возможно. - person Nick Knowlson; 11.05.2012

Обновите свой компилятор.

$ cat test.c
#include <stdio.h>

int main(void)
{
    int foo;
    printf("I am a number: %d \n", foo);
    return 0;
}
$ gcc -Wall -o test ./test.c
./test.c: In function ‘main’:
./test.c:7:11: warning: ‘foo’ is used uninitialized in this function [-Wuninitialized]
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6.1/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.1-9ubuntu3' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3) 
$ 
person Community    schedule 10.05.2012
comment
Я могу подтвердить, что GCC 4.5.3, 4.6.3 и 4.7.0 предупреждают об этом. - person rubenvb; 11.05.2012
comment
@rubenvb: Вы можете (вероятно) только подтвердить, что ваш дистрибутив имеет достаточно хорошие настройки в профиле по умолчанию, чистый ванильный gcc даже не включает оптимизацию (-O, ни --march=native, --mtune=native, ни графита, ни ничего такого). Mea culpa, если вы скомпилировали gcc вручную и можете сказать обратное. - person Tomas Pruzina; 11.05.2012
comment
Его проблема, скорее всего, связана с использованием дистрибутивной версии пакета Apple, llvm является интерфейсом, который также устарел (устарел) на самом деле. - person Tomas Pruzina; 11.05.2012
comment
@AoeAoe, на самом деле, я сам собрал GCC и не возился с профилем по умолчанию (или с переменной среды CFLAGS, я в Windows ;-)). - person rubenvb; 11.05.2012

Стандарт C не требует от компилятора предупреждения о доступе к неинициализированной переменной. От компилятора даже не требуется предупреждать, если программа вызывает неопределенное поведение (при условии отсутствия синтаксической ошибки и нарушений ограничений).

С помощью gcc вы можете включить предупреждения для неинициализированных переменных с помощью -Wuninitialized. Как отмечали другие, в последних версиях gcc -Wuninitialized включается, когда указано -Wall.

person ouah    schedule 10.05.2012
comment
Я ценю усилия, но я уже знаком со всем этим. :) - person Nick Knowlson; 11.05.2012
comment
Кроме того, мне было любопытно, и оказалось, что -Wuninitialized был включен, когда указано -Wall, по крайней мере, начиная с версии 2.95.3 (16 марта 2001 г.). Так что не так уж и недавно! :) gcc.gnu.org/onlinedocs/gcc-2.95. 3/gcc_2.html#SEC8 - person Nick Knowlson; 11.05.2012