轻松找到未初始化的成员变量

时间:2010-01-20 07:29:01

标签: c++ findbugs initialization

我正在寻找一种简单的方法来查找未初始化的类成员变量。

运行时编译时中查找它们是可以的。

目前我在类构造函数中有一个断点,并逐个检查成员变量。

11 个答案:

答案 0 :(得分:28)

如果使用GCC,则可以使用-Weffc++标志,该标志在成员初始化列表中未初始化变量时生成警告。这样:

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++也会在变量具有正确的默认构造函数时发出警告,因此不需要初始化。它还会在构造函数中初始化变量时向您发出警告,但不会在成员初始化列表中发出警告。它警告许多其他C ++样式问题,例如缺少复制构造函数,因此当您想要定期使用-Weffc++时,可能需要稍微清理一下代码。

还有一个错误导致它在使用匿名联合时总是给你一个警告,你目前无法解决其他问题,然后关闭警告,这可以通过以下方式完成:

#pragma GCC diagnostic ignored "-Weffc++"

总的来说,我发现-Weffc++对于捕捉大量常见的C ++错误非常有用。

答案 1 :(得分:10)

Valgrind可以告诉你你是否在linux上。

答案 2 :(得分:10)

Valgrind FREE ,在Linux上)和Purify(在Windows上)通过在特殊虚拟机中运行代码来查找未初始化的变量,无效指针等

这很容易使用且功能非常强大;它可能会发现除了明显的未初始化变量之外的许多错误。

CoverityKlocworkLint可以使用静态代码分析找到未初始化的变量。

答案 3 :(得分:10)

cppcheck会找到这个,例如:

cppcheck my_src_dir --output-file=check.txt --inconclusive --enable=warning

答案 4 :(得分:6)

-Wuninitialized

(这只检查变量是否未经初始化使用,即

struct Q { 
  int x, y;
  Q() : x(2) {}
  int get_xy() const { return x*y; }
};
仅当用户在未指定get_xy()的情况下调用y时,g ++才会发出警告。)

答案 5 :(得分:5)

Visual Studio(MSVC)具有/ sdl(启用其他安全检查)编译器选项(http://msdn.microsoft.com/en-us/library/jj161081.aspx)。在运行时,它:

  

执行类成员初始化。自动初始化类   对象实例化时指针类型的成员为零(在。之前)   构造函数运行)。这有助于防止使用未初始化的数据   与构造函数未显式的类成员相关联   初始化。

这不会帮助您在编译时检测未初始化的成员变量,但是当它在运行时发生时,它会使行为更具可预测性。当然,你不应该编写依赖于此选项的代码。

答案 6 :(得分:4)

如果您使用的是Visual Studio,则可以在调试模式下编译,在调试器中停止该程序,并查找哪些变量初始化为包含0xCC(堆栈)或0xCD(堆)的字节。

虽然就个人而言,我会投入静态分析工具以获得更彻底的方法。

答案 7 :(得分:2)

/analyze on Visual Studio(“团队系统”)

答案 8 :(得分:0)

小心!这里提出的编译器选项既不可靠,也不依赖于版本。考虑一个简单的例子:

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编译此事件报告uninitialized在gcc版本中高达4.6(包括在内),并且在4.7和4.8(在MacPorts上测试)中愉快地通过。然后,奇怪的是,如果我们删除printf("haha");,4.7和4.8都会突然看到uninitialized A::aClang稍微好一点,因为它以某种方式将垃圾(而不是方便的0)分配给未初始化的变量,因此您可以更轻松/更快地看到它们的灾难性影响。

我发现上面未初始化的A::a valgrind并没有太多运气;也许建议valgrind的温和可以提供适当的选项来发现这个错误。

底线:很好的问题,目前还没有太多可靠的解决方案......(我看待它的方式)。

答案 9 :(得分:0)

clang with clang-analyze能够做到这一点。它将事件创建一个很好的HTML报告,指示何时访问未使用的变量。

答案 10 :(得分:-2)

考虑以下代码

unint.cpp:

int main()
{
    int a;
    int b;
    a++;
    b = b + 5;

    return 0;
}

如果使用以下注释编译代码,则应显示警告消息。

g ++ -O3 -Wuninitialized unint.cpp

注意:-Wuninitialized也需要-O3选项。