Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在编译时检测或防止未初始化的数组元素?_C_Arrays_Static Analysis - Fatal编程技术网

C 如何在编译时检测或防止未初始化的数组元素?

C 如何在编译时检测或防止未初始化的数组元素?,c,arrays,static-analysis,C,Arrays,Static Analysis,下面的示例显示了使用未初始化数组元素的代码: #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 */ retu

下面的示例显示了使用未初始化数组元素的代码:

#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;
}
编译器可能认为
str
实际上是初始化的,因为指针本身有一个值。只是它的元素没有初始化。因此,编译器是正确的

另一方面,编译器明确地决定不在这里插入任何元素的初始化,因此它知道数组中未初始化的元素。那它为什么不发出警告呢


是否有任何编译器设置或其他工具可以帮助在编译时检测此问题?我对任何C编译器都感兴趣,不仅仅是
gcc

我不知道gcc会发现这种未初始化的缓冲区问题。有一些静态分析工具将尝试更好地检测未初始化的变量。运行时确实会检测到某些错误,尽管这并不是最有用的信息:

$ 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

考虑以下几点。第一个
printf()
具有定义良好的行为,即使
str[]
的元素未初始化。接下来的两个有问题

为了使编译器能够区分,它需要分析代码。由于C标准不需要这种级别的分析,符合要求的编译器可能无法检测,因此也就没有编译器设置

各种工具和编译器都会分析代码

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

虽然不是静态分析,但valgrind在运行时找到这样的东西是非常宝贵的。非常有趣@reiniertorenbeek谢谢,我会检查Splint。
char str[10];
printf("<%.*s>\n", 0, str);
printf("<%.*s>\n", 1, str);
printf("<%s>\n", str);
char str[10] = "";  // or = {0};
strcpy(str, "ABC");