52

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

在运行时编译时找到它们都可以。

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

4

11 回答 11

32

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

还有一个错误会导致它在使用匿名联合时始终向您发出警告,您目前无法解决此问题,然后关闭警告,可以通过以下方式完成:

#pragma GCC diagnostic ignored "-Weffc++"

但总的来说,我发现-Weffc++它在捕捉许多常见的 C++ 错误方面非常有用。

于 2010-05-26T09:42:58.873 回答
11

cppcheck会找到这个,例如:

cppcheck my_src_dir --output-file=check.txt --inconclusive --enable=warning
于 2011-04-11T19:09:39.637 回答
10

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

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

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

于 2010-01-20T08:14:14.757 回答
9

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

于 2010-01-20T08:10:07.397 回答
7

-Wuninitialized?

(这仅检查变量是否未初始化,即如果

struct Q { 
  int x, y;
  Q() : x(2) {}
  int get_xy() const { return x*y; }
};

g++ 只会在用户调用get_xy()而不分配给时发出警告y。)

于 2010-01-20T07:35:34.653 回答
5

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

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

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

于 2014-10-12T10:08:48.747 回答
4

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

尽管就个人而言,我会投资于静态分析工具以获得更彻底的方法。

于 2010-01-20T11:02:19.590 回答
2

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

于 2010-01-20T15:30:51.300 回答
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了高达 4.6 的 gcc 版本,并在 4.7 和 4.8 上顺利通过(在 MacPorts 上测试)。然后,奇怪的是,如果我们去掉printf("haha");, 4.7 和 4.8 都会突然看到uninitialized A::aClang稍微好一点,因为它以某种方式将垃圾(而不是方便0)分配给未初始化的变量,因此您更容易/更快地看到它们的灾难性影响。

我没有太多运气发现上述未初始化A::a的内容valgrind;也许建议的绅士valgrind可以提供适当的选择来发现这个错误。

底线:很好的问题,目前没有多少可靠的解决方案......(我的看法)。

于 2013-06-21T10:17:07.893 回答
0

带有 clang-analyze 的 Clang 能够做到这一点。它将创建一个漂亮的 HTML 报告,指示何时访问未使用的变量。

于 2016-06-11T15:11:15.993 回答
-2

考虑以下代码

unint.cpp:

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

    return 0;
}

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

g++ -O3 -Wuninitialized unint.cpp

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

于 2013-04-25T11:02:24.790 回答