3

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.

2
  • 2
    Though not static analysis, valgrind is invaluable to find stuff like this at runtime. Commented Nov 30, 2015 at 15:41
  • 1
    quite fascinating @ReinierTorenbeek Commented Nov 30, 2015 at 15:43

2 Answers 2

1

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
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I will check Splint out.
0

Consider the following. The first printf() has well defined behavior even though the elements of str[] are not initialized. The next 2 have problems.

For a compiler to distinguish, it needs to analyze the code. As the C standard does not require this level of analysis, a compliant complier may have no ability to detect and thus no compiler settings.

Various tools and compilers do analyze code.

char str[10];
printf("<%.*s>\n", 0, str);
printf("<%.*s>\n", 1, str);
printf("<%s>\n", str);

Another approach is to code defensively. Simple initialize the array. A good compiler in the following case would detect the unnecessary initialization and optimize it out.

char str[10] = "";  // or = {0};
strcpy(str, "ABC");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.