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
Проблемът му е просто с използването на apples dist версия на пакета, llvm е front-end също е остарял (отхвърлен) afaik. - 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