Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 查找未初始化成员变量的简便方法_C++_Findbugs_Initialization - Fatal编程技术网

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

C++ 查找未初始化成员变量的简便方法,c++,findbugs,initialization,C++,Findbugs,Initialization,我正在寻找一种查找未初始化的类成员变量的简单方法 可以在运行时或编译时找到它们 目前,我在类构造函数中有一个断点,并逐个检查成员变量。-Wuninitialized (这仅检查变量是否未初始化使用,即 struct Q { int x, y; Q() : x(2) {} int get_xy() const { return x*y; } }; 只有当用户调用get_xy()而不分配给y时,g++才会发出警告。可以告诉您是否在linux上。(linux上免费)和(Windows上

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

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


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

-Wuninitialized

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

struct Q { 
  int x, y;
  Q() : x(2) {}
  int get_xy() const { return x*y; }
};
只有当用户调用
get_xy()
而不分配给
y
时,g++才会发出警告。

可以告诉您是否在linux上。

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

这是易于使用和非常强大的;除了明显的未初始化变量之外,它可能还会发现许多bug


,并可以使用静态代码分析查找未初始化的变量。

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


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

(“团队系统”)

如果使用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++<代码>时,你可能需要清理代码。 还有一个bug导致它在使用匿名联合时总是向您发出警告,您目前无法解决该问题,然后关闭警告,这可以通过以下方式完成:

#pragma GCC diagnostic ignored "-Weffc++"
但是,我发现,<>代码> -WFFC++</代码>对于捕捉许多常见的C++错误是非常有用的。

会发现这一点,例如:

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

考虑以下代码

unint.cpp:

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

    return 0;
}
如果代码中包含以下注释,则应显示警告消息

g++-O3-Wuninitialized unint.cpp


注意,-Wuninitialized还需要-O3选项。

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

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编译
这个东西在gcc版本(包括4.6版)上报告
未初始化
,并在4.7和4.8版(在MacPorts上测试)上通过。然后,奇怪的是,如果我们删除
printf(“哈哈”),4.7和4.8都突然看到
未初始化的A::A
Clang
要好一点,因为它以某种方式将垃圾(而不是方便的
0
)分配给未初始化的变量,因此您可以更容易/更快地看到它们的灾难性影响

我没有太多的运气发现上面未初始化的
A::A
valgrind
;也许
valgrind
可以提供适当的选项来发现此错误

一句话:好问题,目前没有太多可靠的解决方案。。。(在我看来)Visual Studio(MSVC)有一个/sdl(启用附加安全检查)编译器选项()。在运行时,它:

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


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

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

还需要-O1或更高版本,这不是默认值。我无法让g++4.3.3为-Wuninitialized的数据成员发出警告,您确定它在这里有效吗?(简单测试:将
int main(){return Q().get_xy();}
添加到代码中。)@Roger plate:不幸的是,您需要使用
int main(){Q Q;return Q.get_xy()}
来工作。可能是因为cppcheck没有那么聪明。它将警告不要在构造函数中初始化,但它通常无法检查复杂的路径,例如构造函数中的setter初始化成员。自那时以来,Cppcheck得到了改进,版本1.75只能检测部分结构初始化。当然,有些情况下,比如对它来说仍然太难了,尽管对人类来说也很难(正如我观察到的)。它仍然不理解委托构造函数。你确定这对未初始化的成员变量有效吗?在我们的测试中,它只查找未初始化的局部变量。输出:unint.cpp:In函数“int main()”:unint.cpp:8:警告:“a”在此函数中未初始化使用。cpp:9:警告:“b”在此函数中未初始化使用问题的标题是“查找未初始化成员变量的简易方法”。这些不是成员变量。我们都知道非成员变量的
-wInitialized
,我们都应该将其作为已经使用
-Wall-Wextra-Wpedantic
的一部分。此外,它不需要“O3选项”或任何其他形式的优化存在或不存在,尽管它们可能会影响如果优化导致无副作用变量被删除,则返回的警告。对于任何高于
-O0
的优化级别,gcc 4.7优化了除调用
printf
之外的所有内容。我检查了汇编代码