Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect or prevent uninitialized array elements at compile time?

The example below shows code using uninitialized array elements:

#include <stdio.h>

int main(void)
{
    char str[10]; /* elements not initialized */
    int val; /* variable not initialized */

    printf("%s\n", str); /* no warning */
    printf("%d\n", val); /* warning */

    return 0;
}

gcc generates a warning for val but not for str:

$ gcc -Wall -c uninitialized.c 
uninitialized.c:9:20: warning: variable 'val' is uninitialized when used here [-Wuninitialized]
    printf("%d\n", val); /* warning */
                   ^~~
uninitialized.c:6:12: note: initialize the variable 'val' to silence this warning
    int val; /* variable not initialized */
           ^
            = 0
1 warning generated.

The compiler probably concludes that str actually is initialized because the pointer itself has a value. It is just that its elements are not initialized. So the compiler is right.

On the other hand, the compiler explicitly decides not to insert any initialization of the elements here, so it is aware of the uninitialized elements in the array. Then why does it not warn about that?

Are there any compiler settings or other tools that can help to detect this at compile time? I am interested in any C-compiler, not just gcc.

like image 500
Reinier Torenbeek Avatar asked Dec 12 '25 20:12

Reinier Torenbeek


1 Answers

I don't GCC will discover this kind of uninitialised buffer problem. There are static analysis tools that will attempt to do a better job of detecting uninitialised variables. Running split does detect that something is wrong, though it isn't the most informative message:

$ splint quick.c 
Splint 3.1.2 --- 03 May 2009

quick.c: (in function main)
quick.c:8:20: Passed storage str not completely defined (*str is undefined):
                 printf (..., str, ...)
  Storage derivable from a parameter, return value or global is not defined.
  Use /*@out@*/ to denote passed or returned storage which need not be defined.
  (Use -compdef to inhibit warning)
quick.c:9:20: Variable val used before definition
  An rvalue is used that may not be initialized to a value on some execution
  path. (Use -usedef to inhibit warning)

Finished checking --- 2 code warnings
like image 149
N. Leavy Avatar answered Dec 15 '25 10:12

N. Leavy