My GCC 7.3.0 and 8.2.0 has some strange behavior I can't explain. This program, which obviously ends in a Segmentation fault:
int main()
{
double array[2]={0, 0};
printf("%f\n", array[999]);
return 0;
}
Compiled with
gcc -Wall -O2 main.c
Produces the warning
main.c: In function 'main':
main.c:6:5: warning: 'array[999]' is used uninitialized in this function [-Wuninitialized]
printf("%f\n", array[999]);
^~~~~~~~~~~~~~~~~~~~~~~~~~
But with optimization turned off:
gcc -Wall main.c
it produces no warning at all. My Code linter and Debug compile (gcc -g) uses -O0 and didn't pick up on a similar out of bounds error I made, until I compiled it as Release with Optimization turned on. Setting -O1 in the linter posts the warning as expected.
This is a long-standing, documented limitation in GCC. Quoting the manual for GCC 3.0:
-Wuninitialized
Warn if an automatic variable is used without first being initialized or if a variable may be clobbered by a
setjmp
call.These warnings are possible only in optimizing compilation, because they require data flow information that is computed only when optimizing. If you don't specify
-O
, you simply won't get these warnings.
The current version of the manual has actually removed the second paragraph of this quotation, saying instead "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." This is because, at some point between GCC 3.0 (released 2001) and GCC 8.2 (released 2018) the compiler was improved so that it will give warnings for at least some uses of uninitialized variables when not optimizing. For instance, the trivial test
int foo(void) { int x; return x; }
does provoke a warning when compiled with GCC 8.2 using -O0 -Wall
.
It is worth pointing out that perfect diagnosis of uninitialized variables reduces to the infamous Halting Problem—which means it can't be done. You can implement a set of rules that are conservatively correct (they will detect all uses of uninitialized variables, but they may claim that some variables are used uninitialized when they aren't), e.g. Java's definite assignment rules, but that approach has historically been unpopular among C programmers. Given a demand for minimal false positives but also quick compilation when not optimizing, GCC's approach of doing more elaborate analysis when optimization is on is understandable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With