为所有未初始化的变量设置默认值

时间:2020-03-24 23:46:15

标签: c cmake c-preprocessor safety-critical

我有a legacy code,那里有数不清的未初始化

警告C4100 ::未引用的形式参数

或可能未初始化的

警告C4701:使用了可能未初始化的局部变量

变量,稍后可能导致未定义的行为。有没有办法告诉编译器将所有未初始化的变量设置为更易于调试的内容,例如NULL。可能使用其中一个选项

  • 预处理宏
  • 编译器选项
  • CMake选项

例如,考虑以下伪代码:

#include <stdio.h>

int main() {

   int a;

   printf("%d\n",a);

   return 0;
}

我想使用以上任一选项将a设置为NULL之类的所有情况,或者在这种情况下将0设置为NULL

P.S。。在这里,我使用MSVC来捕获可能的问题,但最后,我希望我的解决方案跨平台且与编译器无关。因此,无论如何,编译器特定的解决方案(例如GCC,Clang ...)都受到高度赞赏。

1 个答案:

答案 0 :(得分:4)

这是我的主要评论开头。

我已经克隆了您的开发仓库。

最终,我能够做一个make -i。输出约为500行[错误]。

因此,没有足够的错误来证明自动化脚本的合理性(即,当脚本达到生产质量时,您可以在更少的时间内进行手动检查和修复)。

并且,应该检查某些错误的逻辑错误,尤其是-Wmaybe-unitialized,这是您所关心的。现在可能是确定是否仅将以下内容更改的好时机:将int foobar;更改为int foobar = 0;是可以的。如果是这样,那就是我要做的。 (ie)如果基于if层次结构的代码在未初始化时从不实际上使用该值,则添加int foobar = 0;仅会告诉STFU编译器有关非问题的信息

但是,它实际上可能是一个错误。 如果代码路径已发出警告抱怨 的警告。也许实际上没有显示代码路径,但是在[将来]使用不同的输入数据时,将执行代码 。这将是一个[潜在的]错误。

至少,仅使用= 0;进行初始化会将不可预测的随机副作用转变为可预测的副作用。如果该函数失败,则它将以一致/可预测的方式失败(与之相对的是,依赖于它在[未初始化]堆栈帧中获得的随机值)。

但是,这是时候检查一下[潜在]错误的代码了。您会得到更多的男孩;-)

许多错误为-Wunused-parameter。通常,如果已知能正常工作,我会将-Wno-unused-parameter添加到CFLAGS中。 IMO,实际上,在大多数情况下,这甚至根本不是错误(真实的,虚构的或理论上的错误),这不是错误而不是使用参数,只是一个警告新手编写新代码。如果您具有一个函数签名,该签名具有一个向后兼容性必须保留的额外参数,但替换函数不需要它,则此处将出现误报。

对于-Wunused-but-set-variable,我将删除声明。对int result = important_function_that_changes_globals();进行分类。在那里,保留函数调用。替换为:important_function_that_changes_globals();。或者,如果您必须[而且就我个人而言,从不这样做]:(void) important_function_that_changes_globals();

但是,还有其他一些错误指示(例如)-Wstringop-truncation,它们表示[可能]缓冲区溢出。

src子目录中的代码库为[仅] 30,000行。同样,只有大约500行错误消息。

根据我的经验,这些错误可以在1-3天(最多一周)内进行分类。

但是,正如 jarmod 所指出的那样,可能存在更严重的错误[只有 会在运行时调试中显示]。