轻松find未初始化的成员variables
我正在寻找一种简单的方法来查找未初始化的类成员variables。
在运行时或编译时查找它们是可以的。
目前我在类的构造函数中有一个断点,并逐个检查成员variables。
如果使用GCC,则可以使用-Weffc++
标志,当成员初始化列表中没有初始化variables时,该标志会生成警告。 这个:
class Foo { int v; Foo() {} };
导致:
$ g++ -c -Weffc++ foo.cpp -o foo.o foo.cpp: In constructor 'Foo::Foo()': foo.cpp:4: warning: 'Foo::v' should be initialized in the member initialization list
一个缺点是, -Weffc++
也会在variables有一个合适的默认构造函数的时候发出警告,因此初始化不需要。 当你在构造函数中初始化一个variables时,它也会警告你,而不是在成员初始化列表中。 它会警告许多其他C ++风格的问题,比如缺less复制构造函数,所以当你想定期使用-Weffc++
时候,你可能需要清理一下你的代码。
还有一个错误会导致它在使用匿名联合时总是给你一个警告,而你目前无法解决其他问题,然后closures警告,可以这样做:
#pragma GCC diagnostic ignored "-Weffc++"
总体而言,我发现, -Weffc++
在捕捉大量常见C ++错误方面非常有用。
Valgrind可以告诉你,如果你在Linux上。
Valgrind ( 免费 ,在Linux上)和Purify (在Windows上)通过在特定的虚拟机中运行你的代码find未初始化的variables,无效指针等等。
这很容易使用,非常强大; 它可能会发现许多错误超出了明显的未初始化variables。
Coverity , Klocwork和Lint可以使用静态代码分析find未初始化的variables。
cppcheck会find这个。
-Wuninitialized
?
(这只会检查variables是否使用未初始化,即如果
struct Q { int x, y; Q() : x(2) {} int get_xy() const { return x*y; } };
只有当用户调用get_xy()
而不分配给y
时,g ++才会发出警告。)
Visual Studio(MSVC)具有/ sdl(启用其他安全检查)编译器选项( http://msdn.microsoft.com/en-us/library/jj161081.aspx )。 在运行时,它:
执行类成员初始化。 在对象实例化(在构造函数运行之前)自动初始化指针types的类成员为零。 这有助于防止使用与构造函数没有显式初始化的类成员相关联的未初始化数据。
这不会帮助您在编译时检测未初始化的成员variables,但是当它在运行时发生时,会使行为更具可预测性。 当然,你不应该编写依赖于这个选项的代码。
如果您使用Visual Studio,则可以在debugging模式下进行编译,在debugging器中停止程序,并查找哪些variables被初始化为包含0xCC(堆栈)或0xCD(堆)的字节。
虽然个人,我会投资于一个更彻底的方法静态分析工具。
/ Visual Studio (“Team System”)分析
谨防! 这里提出的编译器选项既不可靠也不独立于版本。 考虑一个简单的例子:
class A { int a; public: void mA() { printf("haha"); ++a; int g = 2/a; printf("%i\n",g); } }; int main() { A a; a.mA(); }
用g++ -O3 -Weffc++ -Wuninitialized
编译g++ -O3 -Weffc++ -Wuninitialized
uninitialized
这个东西在gcc版本上报告没有uninitialized
到4.6(含),并愉快地在4.7和4.8(在MacPorts上testing)上传播。 然后,好奇地,如果我们删除printf("haha");
,4.7和4.8突然看到uninitialized A::a
。 Clang
更好一些,因为它以某种方式将垃圾(而不是方便0
)分配给未初始化的variables,所以您可以更快速地看到它们的灾难性影响。
我用valgrind
发现上面的未初始化的A::a
没有太多的运气; 也许build议valgrind
可以提供适当的选项来发现这个错误。
底线:很好的问题,目前没有太多可靠的解决scheme…(我看到的方式)。
铿锵分析铿锵能够做到这一点。 它将事件创build一个很好的HTML报告,指示何时访问未使用的variables。
考虑下面的代码
unint.cpp:
int main() { int a; int b; a++; b = b + 5; return 0; }
如果代码编译时有以下注释,则应显示警告消息。
g ++ -O3 -Wuninitialized unint.cpp
注意:-Wuninitialized也需要-O3选项。