Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why uninitialized instead of out-of-bounds?

Tags:

c

gcc

gcc-warning

In the code below why is b[9] uninitialized instead of out-of-bounds?

#include <stdio.h>  int main(void) {     char b[] = {'N', 'i', 'c', 'e', ' ', 'y', 'o', 'u', '!'};     printf("b[9] = %d\n", b[9]);      return 0; } 

Compiler call:

% gcc -O2 -W -Wall -pedantic -c foo.c foo.c: In function ‘main’: foo.c:6:5: warning: ‘b[9]’ is used uninitialized in this function [-Wuninitialized]      printf("b[9] = %d\n", b[9]); % gcc --version gcc (Ubuntu 5.4.0-6ubuntu1~16.04.6) 5.4.0 20160609 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

Update: Now this is odd:

#include <stdio.h>  void foo(char *);  int main(void) {     char b[] = {'N', 'i', 'c', 'e', ' ', 'y', 'o', 'u', '!'};     foo(&b[9]);     foo(&b[10]);     printf("b[9] = %d\n", b[9]);     printf("b[10] = %d\n", b[10]);      return 0; } 

Compiling this results in the warnings one would expect:

% gcc -O2 -W -Wall -pedantic -c foo.c foo.c: In function ‘main’: foo.c:9:5: warning: array subscript is above array bounds [-Warray-bounds]      foo(&b[10]);      ^ foo.c:10:29: warning: array subscript is above array bounds [-Warray-bounds]      printf("b[9] = %d\n", b[9]);                              ^ foo.c:11:29: warning: array subscript is above array bounds [-Warray-bounds]      printf("b[10] = %d\n", b[10]); 

Suddenly gcc sees the out-of-bounds for what it is.

like image 845
Goswin von Brederlow Avatar asked Jul 17 '18 12:07

Goswin von Brederlow


People also ask

Are uninitialized variables bad?

An uninitialized variable has an undefined value, often corresponding to the data that was already in the particular memory location that the variable is using. This can lead to errors that are very hard to detect since the variable's value is effectively random, different values cause different errors or none at all.

Are uninitialized variables null in C?

In C, variables with static storage duration that are not initialized explicitly are initialized to zero (or null, for pointers).


1 Answers

I believe this could be the case here: in the first code, GCC notices that you don't need the entire char array at all, just b[9], so it can replace the code with

char b_9; // = ??? printf("b[9] = %d\n", b_9); 

Now, this is a completely legal transform, because as the array was accessed out of bounds, the behaviour is completely undefined. Only in latter phase does it then notice that this variable, which is a substitute for b[9], is uninitialized, and issues the diagnostics message.

Why I believe this? Because if I add just any code that will reference the array's address in memory, for example printf("%p\n", &b[8]); anywhere, the array now is fully realized in memory, and compiler will diagnose array subscript is above array bounds.


What I find even more interesting is that GCC does not diagnose out-of-bounds access at all unless optimizations are enabled. This would again suggest that whenever you're writing a program new program you should compile it with optimizations enabled to make the bugs highly visible instead of keeping them hidden with debug mode ;)