4

I have an example flawed program that should give exactly one warning about an uninitialized variable, but when I compile it gcc doesn't give me any warnings.

Here is the code:

#include <stdio.h>

int main()
{
    int foo;

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

    return 0;
}

Here is what I run: cc -Wall testcase.c -o testcase

And I get no feedback. As far as I know this should produce:

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

It appears to warn Zed Shaw correctly in a similar example in his C tutorial). This is the example I had first tried and noticed that it wasn't working as expected.

Any ideas?

EDIT:

Version of gcc:

i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)
Nick Knowlson
  • 7,185
  • 6
  • 47
  • 63

4 Answers4

8

Are you compiling with optimisation turned on? Here's what my man gcc page says:

  -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.

My version of gcc is:

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

Actually, I just tried this on a gcc 4.4.5 and I do get the warning without using -O. So it depends on your compiler version.

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • Thanks for the answer. I tried `cc -Wall -O testcase.c -o testcase` and `cc -Wuninitialized -O testcase.c -o testcase` with no difference. Also gcc isn't issuing a warning about -Wuninitialized requiring -O. – Nick Knowlson May 10 '12 at 20:08
  • @NickKnowlson: It appears that in gcc 4.2, `-Wall` does not imply `-Wuninitialized`. Also, that version of gcc appears unable to detect that `foo` is in fact unused. – Greg Hewgill May 10 '12 at 20:11
  • http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Warning-Options.html#Warning-Options The docs say otherwise, looks like. "that version of gcc appears unable to detect that foo is in fact unused" So is that the real answer then? This version can't detect foo is uninitialized for some reason? I'll try some more scenarios and see if I can create any conditions where it can. – Nick Knowlson May 10 '12 at 20:17
2

Update your compiler.

$ 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) 
$ 
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
  • 4
    I can confirm GCC 4.5.3, 4.6.3, and 4.7.0 all warn on this. – rubenvb May 10 '12 at 20:03
  • @rubenvb: You can (probably) only confirm that your distro has reasonably nice settings in default profile, pure vanilla gcc does not even turn optimizations on (-O, nor --march=native, --mtune=native, no graphite no nothing). Mea culpa if you have compiled gcc by hand and can say otherwise. – Tomas Pruzina May 11 '12 at 11:59
  • His problem is prolly with using apples dist version of package, llvm is front-end is also obsolete (deprecated) afaik. – Tomas Pruzina May 11 '12 at 12:00
  • 1
    @AoeAoe as a matter of fact I did build GCC myself, and did not mess with the default profile (or with the `CFLAGS` environment variable, I'm on Windows `;-)`). – rubenvb May 11 '12 at 12:25
0

A compiler is not required by the C Standard to warn when an uninitialized variable is accessed. A compiler is even not required to warn if a program invokes undefined behavior (assuming there is no syntax error and no constraint violations).

With gcc you can enable warnings for uninitialized variables with -Wuninitialized. As others noted, with recent versions of gcc, -Wuninitialized is enabled when -Wall is specified.

ouah
  • 142,963
  • 15
  • 272
  • 331
  • I appreciate the effort, but I am already familiar with all this. :) – Nick Knowlson May 10 '12 at 20:10
  • Also, I was curious about this and it appears `-Wuninitialized` has been enabled when `-Wall` is specified at least since version 2.95.3 (March 16, 2001). So not too recent anymore! :) http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_2.html#SEC8 – Nick Knowlson May 10 '12 at 20:24
0

Use Clang, be done with it. Seems like a bug in GCC, cause Clang warns like it should.

rubenvb
  • 74,642
  • 33
  • 187
  • 332