cgcc

gcc compiler -Wmaybe-uninitialized not triggering in switch statement


I enabled the -Wmaybe-uninitialized option to try to catch problems in a state machine I was writing. The state machine is using classic switch / case method. I found that it did not catch uninitialized variables in some cases, and I can't explain why. It looks almost like bug in gcc, but thought I would ask here first.

Here's the minimal code demonstrating the issue...

#include <stdio.h>

int func(int event)
{
    int status;
    switch (event)
    {
    case 0:
        status = 0;
        break;
    case 1:
        status = 1;
        break;
    default:
        //printf("status = %d\n", status);
        break;
    }
    return status;
}

int main(void)
{
    printf("status = %d\n", func(0));
    printf("status = %d\n", func(1));
    printf("status = %d\n", func(2));

    return 0;
}

You can see from the code, that the the variable status was not initialized and the default case does not set it, yet it is returned apparently uninitialized and no warning was given by gcc.

The output when run is...

status = 0
status = 1
status = 1

If I uncomment the printf in the default case, which tries to print status, then the warning does trigger (correctly), but not in the return statement (or in fact in any use outside of the switch it seems).

Can anyone explain this.

The version of gcc I am using is: gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-21)

I am using -Werror, -Wall and -Wextra options to gcc. Note, the -Wextra enables -Wmaybe-uninitialized (also tried with this explicitly).


Solution

  • This is one of the warnings that depends on analysis done by the optimiser. If you're not optimising, you don't get the benefit of this one. The manual says:

    -Wmaybe-uninitialized

    ...

    These warnings are only possible in optimizing compilation, because otherwise GCC does not keep track of the state of variables.

    It turns out that -Og is a sufficient level to enable this warning.