C++ 查找未初始化成员变量的简单方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2099692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:05:55  来源:igfitidea点击:

Easy way find uninitialized member variables

c++findbugsinitialization

提问by user254669

I am looking for an easy way to find uninitialized class member variables.

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

Finding them in either runtimeor compile timeis OK.

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

Currently I have a breakpoint in the class constructor and examine the member variables one by one.

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

回答by Grumbel

If you use GCC you can use the -Weffc++flag, which generates a warnings when a variable isn't initialized in the member initialisation list. This:

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

class Foo
{
  int v;
  Foo() {}
};

Leads to:

造成:

$ 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

One downside is that -Weffc++will also warn you when a variable has a proper default constructor and initialisation thus wouldn't be necessary. It will also warn you when you initialize a variable in the constructor, but not in the member initialisation list. And it warns on many other C++ style issues, such as missing copy-constructors, so you might need to clean up your code a bit when you want to use -Weffc++on a regular basis.

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

There is also a bug that causes it to always give you a warning when using anonymous unions, which you currently can't work around other then switching off the warning, which can be done with:

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

#pragma GCC diagnostic ignored "-Weffc++"

Overall however I have found -Weffc++to be incredible useful in catching lots of common C++ mistakes.

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

回答by Johan Kotlinski

cppcheckwill find this, e.g.:

cppcheck会找到这个,例如:

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

回答by Zitrax

Valgrindcan tell you if you are on linux.

Valgrind可以告诉你你是否使用 Linux。

回答by Will

Valgrind(FREE, on Linux) and Purify(on Windows) find un-initialized variables, invalid pointers and such by running your code in a special virtual machine.

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

This is easy to use and extremely powerful; it will likely find many bugs beyond the obvious un-initialized variables.

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

Coverity, Klocworkand Lintcan find un-initialized variables using static code analysis.

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

回答by kennytm

-Wuninitialized?

-Wuninitialized?

(This only checks if a variable is used uninitialized, i.e. if

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

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

g++ will warn only when the user calls get_xy()without assigning to y.)

g++ 只会在用户get_xy()未分配给y.) 的情况下调用时发出警告。

回答by Quatari

Visual Studio (MSVC) has a /sdl (Enable Additional Security Checks) compiler option (http://msdn.microsoft.com/en-us/library/jj161081.aspx). At run-time, it:

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

Performs class member initialization. Automatically initializes class members of pointer type to zero on object instantiation (before the constructor runs). This helps to prevent use of uninitialized data associated with class members that the constructor does not explicitly initialize.

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

This will not help you detect uninitialized member variables at compile-time, but it makes the behaviour more predictable when it happens at run-time. You shouldn't write code that relies on this option being enabled though, of course.

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

回答by Kaz Dragon

If you're using Visual Studio, you could compile in debug mode, stop the program in the debugger and look for which variables are initialised to bytes containing 0xCC (stack) or 0xCD (heap).

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

Though personally, I'd invest in a static analysis tool for a more thorough approach.

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

回答by Terry Mahaffey

/analyze on Visual Studio("Team System")

/ 分析 Visual Studio(“团队系统”)

回答by Jean-Micha?l Celerier

Clang with clang-analyze is able to do this. It will event create a nice HTML report that indicates when the unused variable is accessed.

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

回答by P Marecki

Beware! Compiler options proposed here are neither reliable, nor version-independent. Consider the simple example:

谨防!此处提出的编译器选项既不可靠,也不独立于版本。考虑一个简单的例子:

class A {
  int a;
public:
  void mA() {
    printf("haha");
    ++a;
    int g = 2/a;
    printf("%i\n",g);
  }
};

int main() {
  A a;
  a.mA();
}

Compiled with g++ -O3 -Weffc++ -Wuninitializedthis thing reports uninitializedon gcc versions up to 4.6 inclusive, and passess happily on 4.7 and 4.8 (tested on MacPorts). Then, curiously, if we remove the printf("haha");, both 4.7 and 4.8 suddenly see uninitialized A::a. Clangis a little better, since it somehow assigns rubbish (instead of convenient 0) to uninitialized vars, so you see their disastrous effect easier/sooner.

g++ -O3 -Weffc++ -Wuninitialized这个东西编译,报告uninitializedgcc 版本高达 4.6,并在 4.7 和 4.8 上愉快地通过(在 MacPorts 上测试)。然后,奇怪的是,如果我们删除printf("haha");, 4.7 和 4.8 都会突然看到uninitialized A::aClang好一点,因为它以某种方式将垃圾(而不是方便0)分配给未初始化的变量,因此您可以更容易/更快地看到它们的灾难性影响。

I didn't have much luck in spotting the above uninitialized A::awith valgrindeither; maybe the gentlement suggesting valgrindcould provide appropriate options to spot this error.

我没有在发现上述未初始化的运气A::avalgrind两种; 也许先生的建议valgrind可以提供适当的选择来发现这个错误。

Bottom line: great question, not much reliable solutions at the moment... (the way I see it).

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