9

So let's say I'm careless and make a stupid typo.. this file:

test.c

#include <stdio.h>

int main()
{
    int x = x;
    printf("%d\n",x);
}

compiles fine:

mymachine:~ oll$ gcc test.c 
mymachine:~ oll$ ./a.out 
1782198366

Obviously int x = x is a mistake but the compiler accepts this without warning. I've wasted quite a few hours trying to this error.

Is there a compiler flag that and can use for gcc / g++ to make the compiler give me a warning when I use an uninitialised stack variable? This could potentially save me a lot of time in the future.

I have tried gcc -O -Wuninitialized test.c - didn't work.

Thanks in advance

Edit: I have tried -Wall, no mention of x

mymachine:~ oll$ gcc -Wall test.c 
test.c: In function ‘main’:
test.c:7: warning: control reaches end of non-void function

Edit: Solution found

It seems that using the command line tools gcc and g++ in OS X 10.8 doesn't give this warning, using clang works:

mymachine:~ oll$ clang -Wall test.c
test.c:5:10: warning: variable 'x' is uninitialized when used within its own initialization [-Wuninitialized]
        int x = x;
        ~   ^
1 warning generated.
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
OLL
  • 655
  • 5
  • 20
  • 5
    You should **always** be using `gcc -Wall ...` – Paul R Apr 09 '14 at 13:04
  • [asked something similar for Visual Studio](http://stackoverflow.com/questions/20116684/why-doesnt-visual-studio-fire-a-warning-at-self-assignment-int-foo-foo), still waiting for an answer – UmNyobe Apr 09 '14 at 13:04
  • You can set the compilation as stricter. See related info here: http://stackoverflow.com/questions/490737/making-gcc-and-other-c-compilers-very-strict – adripanico Apr 09 '14 at 13:04
  • -Wall gives me a `test.c:7: warning: control reaches end of non-void function`, no mention of x – OLL Apr 09 '14 at 13:05
  • 1
    FWIW, clang produces `warning: variable 'x' is uninitialized when used within its own initialization [-Wuninitialized]`. – Stephen Canon Apr 09 '14 at 13:06
  • `gcc (GCC) 4.8.2` under Cygwin **needs** `-Wuninitialized -Winit-self` even if `-Wall -Wextra -pedantic` are given already to issue `warning: ‘x’ is used uninitialized in this function [-Wuninitialized]`. – alk Apr 09 '14 at 14:38

2 Answers2

9

It looks like the warning flags you want are -Wuninitialized -Winit-self (see it live):

Warn about uninitialized variables that are initialized with themselves. Note this option can only be used with the -Wuninitialized option.

For example, GCC warns about i being uninitialized in the following snippet only when -Winit-self has been specified:

int f()
{
    int i = i;
    return i;
}

This warning is enabled by -Wall in C++.

Based on the comments below there may be some version dependencies. Note, that clang generates a warning for this just using -Wall, which seems more sensible to me:

warning: variable 'x' is uninitialized when used within its own initialization [-Wuninitialized]
int x = x;
    ~   ^

The live example I linked above also includes a commented out clang command line.

Also see Why is -Winit-self separate from -Wuninitialized.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • That doesn't seem to make any difference in this case - did you try it ? – Paul R Apr 09 '14 at 13:08
  • @PaulR added live example from Coliru – Shafik Yaghmour Apr 09 '14 at 13:09
  • Works fine for me, on `gcc`, only if I use it along with `-Wall` or along with `-Wuninitialized` – chrk Apr 09 '14 at 13:09
  • OK - it doesn't seem to work with my version of gcc. – Paul R Apr 09 '14 at 13:10
  • @PaulR _This warning is enabled by -Wall **in C++.**_ and op has the question tagged with C. That might be very relevant here. `-Winit-self` might need to be specified directly. – cf- Apr 09 '14 at 13:10
  • Nope - neither `gcc -Wall -Winit-self` nor `g++ -Wall -Winit-self` works for me. – Paul R Apr 09 '14 at 13:11
  • The pasted document states `Note this option can only be used with the -Wuninitialized option.` suggesting that by itself it has no function (strange) and that `-Wuninitialized` won't catch it otherwise (also strange since while uninitialized it's used to initialize itself). I believe that while `-Wall` is not truly _all_ warnings, that it does envelop `-Wuninitialized` – mah Apr 09 '14 at 13:12
  • @ShafikYaghmour I tried `-Wall` with `g++`. Didn't work. `g++` version I am using is `g++ (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3` – ajay Apr 09 '14 at 13:12
  • @ajay what are your results if you include `-Wextra`? – mah Apr 09 '14 at 13:13
  • @mah I get the same result. It compiles fine without any warning. Using the flag `-Winit-self` throws the warning. – ajay Apr 09 '14 at 13:16
  • @mah Clang throws the warning on `-Wall` flag itself. Does it mean clang is a better compiler than gcc? – ajay Apr 09 '14 at 13:18
  • ah... using `clang` worked.. using `gcc` or `g++` didn't.. odd (I'm on OS X btw) – OLL Apr 09 '14 at 13:22
  • 1
    @ajay I personally feel clang is a better compiler but I have nothing solid to back that up with. It probably helps that I am primarily developing on OS X these days too, and a good percentage of my work is using Objective C. – mah Apr 09 '14 at 13:27
  • Why would you ever want `-Wuninitialized` but _not_ `-Winit-self`? What situation is self-initialization not a potential bug? – AShelly Apr 09 '14 at 13:30
  • I re-asked and got a good answer [here](http://stackoverflow.com/q/22965414/10396): – AShelly Apr 09 '14 at 16:31
  • @nos that was exactly my answer [here](http://stackoverflow.com/questions/22965414/why-is-winit-self-separate-from-wuninitialized/22965534#22965534). – Shafik Yaghmour Apr 09 '14 at 21:50
0

Often, with any compiler, aggressive optimisation options will generate warnings not issued during normal compilation, including uninitialised or potentially uninitialised variables in far more complex situations that described in this question.

This is possible due to the execution analysis necessary to perform optimisation. So as a general recommendation, it is worth applying optimisation at the highest possible level (-O3 for example), as a kind of "poor man's static analysis", even if you do not intend to deploy with optimisation at that level.

Clifford
  • 88,407
  • 13
  • 85
  • 165