我在下面有一个小程序,该程序在结构中使用未初始化的字段。我用-Wuninitialized -Wmissing-field-initializers -Wall -Wextra -Werror
(下面的Godbolt链接)编译程序,该程序编译正常并运行,但是在读取结构时会打印未初始化的垃圾值。
是否有一种方法可以警告使用未初始化变量的这种编程错误?
#include <stdio.h>
enum FWPixelDepth {
FWPixelDepthColor8888,
};
struct FWBitmapDecodeOptions {
FWPixelDepth pixelDepth;
float scale;
bool decodeWithoutPremultiply;
};
static void p(FWBitmapDecodeOptions opts) {
printf("%d, %f, %d", opts.pixelDepth, opts.scale, opts.decodeWithoutPremultiply);
}
int main() {
FWBitmapDecodeOptions opts;
opts.decodeWithoutPremultiply = true;
p(opts);
}
Clang 8.0.0标志:-O3 -Wuninitialized -Wmissing-field-initializers -Wall -Wextra -Werror
样本输出:
-1557482600, 0.000000, 1
答案 0 :(得分:3)
与其他编程语言相反,在C ++中,使用时通常无法在运行时检测带有POD type的变量是否已初始化。为了检测到这一点,每个变量都需要一个关联的标志,该标志指定变量是否已初始化。这将花费大量的空间和性能。因此,这种运行时检查通常仅由某些高级编程语言完成。
但是,在简单的情况下,当可能的代码路径数量非常有限时,编译器可能会检测到对未初始化数据的读取访问。但是,这注定是不可靠的,因为不能期望编译器总是能够检查所有可能的代码路径。
因此,为了检测对未初始化数据的读取访问,最好使用特殊的调试工具,该工具在运行时检测此类错误并为此牺牲性能。此类工具的示例为valgrind和Clang memory sanitizer。