2

I know there is a uninitialized warning in gcc that can tell you if a variable is uninitialized. This is clear to me. But I want to know what is "Maybe-Initialized" warning?

Is gcc not sure if this is initialized or not. Or consider this, the code is initializes properly and gcc think "maybe" it is not initialized. If the compiler is not sure why I should have this warning at all?

Now I can disable the warning with -Wno-maybe-uninitialized or do a fix in the code.

But my question is what does this means? Why gcc thinks it maybe uninitialized. gcc is sure that the variable is initialized because I am not getting -Wuninitialized.

I am using GCC 4.8 Fedora 21 x86_64.

Also I would appreciate if someone could show how this warning is triggered.

pevik
  • 4,523
  • 3
  • 33
  • 44
rkm
  • 892
  • 2
  • 16
  • 32
  • To fix the warning you can initialize your variable to some default value such as 0. It's probably better to use the wrong value of 0 by accident than an uninitialized value which causes undefined behavior. Lesser of two evils. – Neil Kirk Nov 29 '15 at 11:40
  • agreed. But that shouldn't be Wunitialized warning?. – rkm Nov 29 '15 at 11:45
  • As explained in the answer, gcc cannot be sure if the uninitialized usage occurs or not. – Neil Kirk Nov 29 '15 at 11:47
  • so the variable might be initialized properly but gcc throws warning. – rkm Nov 29 '15 at 11:50
  • okay. i found there is bug in gcc verion.https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47679 – rkm Nov 29 '15 at 11:52
  • 1
    Yes. It may be uninitialized, but maybe not. – Neil Kirk Nov 29 '15 at 11:53

2 Answers2

9

There are cases when the compiler can detect clearly that something isn't initialized:

void func1(int x);  

void func()
{
    int x;
    func1(x);   // x is definitely not initialized when calling func1;
}

But in some cases, the variable CAN have been initialized:

void func(int y)
{
   int x;
   if (y == 1)
       x = 7;
   else if (y == 2)
       x = 14;
   // If we get here, is x initialized or not?
   func1(x);
}

Now, if you and I know for sure that y is ALWAYS onw or two, then the above code has no problem. However, if we call it with y as three, x has not been initialized, and func1 will operate on an unspecified value. If you enable -Wmaybe-uninitialized, the compiler will warn for that case.

The workaround is to tell the compiler not to expect any other value, for example using an assert:

void func(int y)
{
   int x;
   assert( y == 1 || y == 2 && "Can't deal with y not in { 1, 2 } ");
   if (y == 1)
       x = 7;
   else if (y == 2)
       x = 14;
   // If we get here, is x initialized or not?
   func1(x);
}

Now, the compiler will know that the result of the assert doesn't allow y to be anything other than 1 or 2, and thus all valid values are covered. Invalid values are caught by the assert which doesn't return.

[Of course, the standard does not state that the assert has this effect. It is an effect of call-flow analysis in conjunction with data-flow analysis and understanding of what assert does - I know gcc and clang both understand this sort of construct and will happily aceept the above code without warning]

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
3

You should really look into GCC manual before asking such questions.

For an automatic variable, if there exists a path from the function entry to a use of the variable that is initialized, but there exist some other paths for which the variable is not initialized, the compiler emits a warning if it cannot prove the uninitialized paths are not executed at run time. These warnings are made optional because GCC is not smart enough to see all the reasons why the code might be correct in spite of appearing to have an error.

This warning is generated not when GCC is not sure if a variable is initialized or not. It's issued when a variable is not always initialized.

Here is slightly modified example from the manual:

void foo(int y)
{
    int x;
    switch (y)
    {
        case 1: x = 1;
        break;
        case 2: x = 4;
        break;
        case 3: x = 5;
    }
    bar(x);
}
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • 1
    this is uninitialized warning. my question is about maybe-uninitialized – rkm Nov 29 '15 at 11:46
  • http://stackoverflow.com/questions/14132898/gcc-wuninitialized-wmaybe-uninitialized-issues – rkm Nov 29 '15 at 11:51
  • @rashad Meh. I don't understand what you're talking about. I quoted GCC manual for `-Wmaybe-uninitialized` (https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html) and you're saying `this is uninitialized warning. my question is about maybe-uninitialized`. – HolyBlackCat Nov 29 '15 at 12:07
  • @rashad I copied it from GCC manual. From `maybe-uninitialized` description. I only made minor modifications. – HolyBlackCat Nov 29 '15 at 19:11
  • but when i tried to compile. I got unintialized warnings with gcc -O2 – rkm Nov 30 '15 at 08:25
  • i have gcc installed from fedora 20 x86_64. gcc version 4.8.3 20140911 (Red Hat 4.8.3-7) (GCC). A bug inside gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47679 – rkm Nov 30 '15 at 17:41