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");