GCC -Wuninitialized / -Wmaybe-uninitialized issues

user593062 picture user593062 · Jan 3, 2013 · Viewed 20.6k times · Source

I am experiencing a very strange issue using gcc-4.7 (Ubuntu/Linaro 4.7.2-11precise2) 4.7.2. I am unable to compile the following valid code without a warning:

extern void dostuff(void);

int test(int arg1, int arg2)
{
    int ret;

    if (arg1) ret = arg2 ? 1 : 2;

    dostuff();

    if (arg1) return ret;

    return 0;
}

Compile options and output:

$ gcc-4.7 -o test.o -c -Os test.c -Wall
test.c: In function ‘test’:
test.c:5:6: warning: ‘ret’ may be used uninitialized in this function [-Wmaybe-uninitialized]

However, the following code compiles with no warning (albeit to slightly less efficient assembly):

extern void dostuff(void);

int test(int arg1, int arg2)
{
    int ret;

    if (arg1 && arg2) ret = 1;
    if (arg1 && !arg2) ret = 2;

    dostuff();

    if (arg1) return ret;

    return 0;
}

I am somewhat stuck and am considering this a compiler bug. Any thoughts?

Answer

Alok Save picture Alok Save · Jan 3, 2013

Indeed this is a known problem in gcc.
gcc is notorious for reporting incorrect uninitialized variables.
The shortcomings have been duly noted and there is a initiative to overcome the shortcomings:
Better Uninitialized Warnings:

The GNU Compiler Collection warns about the use of uninitialized variables with the option -Wuninitialized. However, the current implementation has some perceived shortcomings. On one hand, some users would like more verbose and consistent warnings. On the other hand, some users would like to get as few warnings as possible. The goal of this project is to implement both possibilities while at the same time improving the current capabilities.

The initiative aims at providing better warnings and it quotes a example case similar as your case. The relevant portion being:

What an user understands as a false positive may be different for the particular user. Some users are interested in cases that are hidden because of actions of the optimizers combined with the current environment. However, many users aren't, since that case is hidden because it cannot arise in the compiled code. The canonical example is

int x;
if (f ())
     x = 3;
return x;

where 'f' always return non-zero for the current environment, and thus, it may be optimized away. Here, a group of users would like to get an uninitialized warning since 'f' may return zero when compiled elsewhere. Yet, other group of users would consider spurious a warning about a situation that cannot arise in the executable being compiled.