15

Once again a stupid uninitialized variable error in How to fix this segmentation error in a sequence inverting program?.

So I was going to repeat the "please use -Wall flags" comment, but when I tested the code against warnings, I found no warnings reported to my great surprise.

So I trimmed it down to this below (this code makes no sense for execution purposes but it illustrates what I want to show):

#include <stdio.h>

int main()
{

  int i,len=12;

  /* printf("%d\n",i); */

  while(i!=len-1)
  {

    i++;
    len--;
  }

 return 0;
 }

when compiling it using gcc 4.7.3 and 6.2.1 using

gcc -Wall -Wextra -pedantic

I get no warnings, whereas i is blatantly not initialized before using in the while loop.

Now if I uncomment the printf statement I get:

warning: 'i' is used uninitialized in this function [-Wuninitialized]

So why is the warning issued when passing i to printf but not in the while test?

(It's different of gcc failing to warn of uninitialized variable because in my case, there's are no branches)

(Sounds like a bug, but it's so trivial that I wonder if I'm not missing something huge.)

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • why not assign i = 0? – Dr. X Sep 28 '17 at 09:21
  • Do you obtain different results if you force specific versions of the language standard via -std=....? – SirDarius Sep 28 '17 at 09:26
  • @SirDarius nope. same for c99, same for compiling with g++. – Jean-François Fabre Sep 28 '17 at 09:27
  • Commenting `i++` from while loop shows `[-Wuninitialized]` waring. Have no idea why. – svtag Sep 28 '17 at 09:27
  • @Sma good point. Now that's beginning to look like a bug. That said, gcc is optimistic when reporting warnings: when it reports a warning, there's a _real_ problem. But it can fail to report some. – Jean-François Fabre Sep 28 '17 at 09:29
  • @usr yes, looks very much like it. Well, in my case, it's guaranteed that the control flow reaches the `while`. Not the case in the other question. – Jean-François Fabre Sep 28 '17 at 09:30
  • It looks like the `-Wuninitialized` warning is simply not attached to check counter variables within the `while` loop itself. I was surprised to not see a warning here. Intriguing catch. – David C. Rankin Sep 28 '17 at 09:41
  • @DavidC.Rankin I don't know the GCC codebase, but had a case a while ago where **increasing** the optimization level was needed to make a warning appear, so I assume some "unholy" design where the same code is sometimes used for optimization and analysis for warnings... –  Sep 28 '17 at 09:43
  • Does moving the `printf()` to *after* the `while`-loop affect the warning? – Andrew Henle Sep 28 '17 at 09:49

1 Answers1

8

It's hard to say it's a bug, because gcc mixes up code for optimization and for creating warnings, which is even documented for this particular warning:

-Wuninitialized
Warn if an automatic variable is used without first being initialized or if a variable may be clobbered by a setjmp call. [...]
Because these warnings depend on optimization, the exact variables or elements for which there are warnings depends on the precise optimization options and version of GCC used.

(from GCC docs Options to Request or Suppress Warnings, emphasis mine)

You found an IMHO very silly case here. Try -O1 and you'll get an unexpected warning:

warn.c: In function ‘main’:
warn.c:13:6: warning: ‘i’ may be used uninitialized in this function [-Wmaybe-uninitialized]
     i++;
      ^

So, gcc still misses the first uninitialized use, but finds the second one! Try -O0 or -O2 and the warning is again gone...

You could still try to file a bug about this. Note clang gets it right:

warn.c:10:9: warning: variable 'i' is uninitialized when used here
      [-Wuninitialized]
  while(i!=len-1)
        ^
warn.c:6:8: note: initialize the variable 'i' to silence this warning
  int i,len=12;
       ^
        = 0
1 warning generated.