今天我被一个非常愚蠢但很难被发现的bug所击中。以下是相关代码:
class Vector;
class PointIterator {
const Vector & x;
const Vector & yv;
PointIterator(const Vector & xv, const Vector & yvo) :
x(xv), yv(yv) { ;};
// ^^ here is wrong
};
为什么这样的代码是合法的C ++?是否有任何情况可以使用yv
变量?我知道有关int x = x+1;
的类似问题(请参阅this question),但后者未正确初始化,您仍然可以使用x
变量,而在上面的代码中,我认为你不能使用yv
。
加分点:是否有任何编译选项可以让我检测到这个? (最好使用gcc,但我也使用clang),除了“未使用的参数”警告(我有很多这些,我知道我应该清理它们。)
答案 0 :(得分:5)
如果使用g++ -O0 -g main.cpp -Wall -pedantic -Wextra -std=c++14 -o go
main.cpp: In constructor 'PointIterator::PointIterator(const Vector&, const Vector&)':
main.cpp:11:5: warning: 'PointIterator::yv' is initialized with itself [-Winit-self]
PointIterator(const Vector & xv, const Vector & yvo) :
^~~~~~~~~~~~~
main.cpp:11:53: warning: unused parameter 'yvo' [-Wunused-parameter]
PointIterator(const Vector & xv, const Vector & yvo) :
如您所见,您会收到两次警告。一个用于self init,另一个用于未使用的参数。精细!
对于clang来说同样如此:clang++ -O0 -g main.cpp -Wall -pedantic -Wextra -std=c++14 -o go
main.cpp:12:19: warning: reference 'yv' is not yet bound to a value when used
here [-Wuninitialized]
x(xv), yv(yv) { ;};
^
main.cpp:11:53: warning: unused parameter 'yvo' [-Wunused-parameter]
PointIterator(const Vector & xv, const Vector & yvo) :
^
main.cpp:8:20: warning: private field 'x' is not used [-Wunused-private-field]
const Vector & x;
所以clang还报告了这个问题,即在init之前使用了未初始化的ref。精细!
你学到了什么: *使用最高警告级别的多个编译器来获取所有警告!
这就是我们为所有代码所做的工作,特别是在与代码覆盖相关的单元测试中。
您应该使用编码指南,以便通过审核轻松检测此类问题。也许使用" m _"对于班级变革或" _var"参数或任何你喜欢的。只有一个字母列表而不是说出名字的Var名称不太好。