如何在 C++ 中查找和避免未初始化的原始成员?
How to find and avoid uninitialised primitive members in C++?
存在未初始化原始成员的常见 C++ 错误:
#include <iostream>
class A {
public:
int x;
};
int main() {
A a;
std::cout << a.x;
return 0;
}
a.x
将被取消初始化。我理解为什么会发生这种情况,并希望找到一种解决方案来捕获此类错误。我检查了 gcc 和 cppcheck,他们不报告这些成员。
编辑
使用标志 -Wall -Wextra -Werror -pedantic -Wold-style-cast -Wconversion -Wsign-conversion -Wunreachable-code
检查 gcc
检测到错误的第一个 gcc 版本是 5.1。 g++-4.9 检测不到,clang++-3.6 也检测不到。
Yes they do……有点像:
main.cpp: In function 'int main()':
main.cpp:10:18: warning: 'a.A::x' is used uninitialized in this function [-Wuninitialized]
std::cout << a.x;
^
0
在上面的链接示例中,我将 GCC 5.1 trunk 与 -Wall
一起使用。
打开更多 GCC 警告and/or升级。
也测试了,发现不警告:
- 海湾合作委员会 4.4.7
- GCC 4.9.2(来自 RiaD)
- 叮当声 3.6.0
老实说,我不确定您还能做什么。您可以创建一个工具来执行此操作,但随后您将创建一个编译器或静态分析器。 :)
所以,我想,只希望知道如何做到这一点的人赶上来……
此错误由 valgrind
使用(默认)工具 memcheck
诊断,产生了许多警告,包括:
$ valgrind ./unin
…
==12185== Use of uninitialised value of size 8
==12185== at 0x4F39BC3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==12185== by 0x4F3AD89: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==12185== by 0x4F3AF8C: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==12185== by 0x4F474E9: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==12185== by 0x400763: main (in [censored]/unin)
Clang 的地址清理器应该也能找到。但是,我知道您最感兴趣的是编译时检查。毕竟,现有的测试套件可能永远不会执行某些代码,越早发现错误总是越好。您可以使用 GCC 5.1(即使您 仅 用于此目的),或者您可以使用专用的静态分析器。幸运的是,clang 带有一个调用为 scan-build
的静态分析器(至少包含在 Debian/Ubuntu 包中):
$ scan-build clang -c unin.cxx
scan-build: Using '/usr/lib/llvm-3.6/bin/clang' for static analysis
unin.cxx:10:3: warning: Function call argument is an uninitialized value
std::cout << a.x;
^~~~~~~~~~~~~~~~
1 warning generated.
scan-build: 1 bug found.
存在未初始化原始成员的常见 C++ 错误:
#include <iostream>
class A {
public:
int x;
};
int main() {
A a;
std::cout << a.x;
return 0;
}
a.x
将被取消初始化。我理解为什么会发生这种情况,并希望找到一种解决方案来捕获此类错误。我检查了 gcc 和 cppcheck,他们不报告这些成员。
编辑
使用标志 -Wall -Wextra -Werror -pedantic -Wold-style-cast -Wconversion -Wsign-conversion -Wunreachable-code
检测到错误的第一个 gcc 版本是 5.1。 g++-4.9 检测不到,clang++-3.6 也检测不到。
Yes they do……有点像:
main.cpp: In function 'int main()':
main.cpp:10:18: warning: 'a.A::x' is used uninitialized in this function [-Wuninitialized]
std::cout << a.x;
^
0
在上面的链接示例中,我将 GCC 5.1 trunk 与 -Wall
一起使用。
打开更多 GCC 警告and/or升级。
也测试了,发现不警告:
- 海湾合作委员会 4.4.7
- GCC 4.9.2(来自 RiaD)
- 叮当声 3.6.0
老实说,我不确定您还能做什么。您可以创建一个工具来执行此操作,但随后您将创建一个编译器或静态分析器。 :)
所以,我想,只希望知道如何做到这一点的人赶上来……
此错误由 valgrind
使用(默认)工具 memcheck
诊断,产生了许多警告,包括:
$ valgrind ./unin
…
==12185== Use of uninitialised value of size 8
==12185== at 0x4F39BC3: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==12185== by 0x4F3AD89: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==12185== by 0x4F3AF8C: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==12185== by 0x4F474E9: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==12185== by 0x400763: main (in [censored]/unin)
Clang 的地址清理器应该也能找到。但是,我知道您最感兴趣的是编译时检查。毕竟,现有的测试套件可能永远不会执行某些代码,越早发现错误总是越好。您可以使用 GCC 5.1(即使您 仅 用于此目的),或者您可以使用专用的静态分析器。幸运的是,clang 带有一个调用为 scan-build
的静态分析器(至少包含在 Debian/Ubuntu 包中):
$ scan-build clang -c unin.cxx
scan-build: Using '/usr/lib/llvm-3.6/bin/clang' for static analysis
unin.cxx:10:3: warning: Function call argument is an uninitialized value
std::cout << a.x;
^~~~~~~~~~~~~~~~
1 warning generated.
scan-build: 1 bug found.