我最近发现我的 C++ 程序中的大部分错误都是 类似于以下示例的表单:
#include <iostream>
class Z
{
public:
Z(int n) : n(n) {}
int n;
};
class Y
{
public:
Y(const Z& z) : z(z) {}
const Z& z;
};
class X
{
public:
X(const Y& y) : y(y) {}
Y y;
};
class Big
{
public:
Big()
{
for (int i = 0; i < 1000; ++i) { a[i] = i + 1000; }
}
int a[1000];
};
X get_x() { return X(Y(Z(123))); }
int main()
{
X x = get_x();
Big b;
std::cout << x.y.z.n << std::endl;
}
输出:1000
我希望这个程序输出 123(x.y.z.n 的值设置在 get_x()) 但创建“Big b”会覆盖临时 Z。作为 结果,对象 Y 中对临时 Z 的引用现在是 被 Big b 覆盖,因此输出不是我想要的 期待。
当我用带有“-Wall”选项的 gcc 4.5 编译这个程序时,它 没有发出警告。
修复显然是删除对成员 Z 的引用 Y 类。但是,Y 类通常是我没有的库的一部分 开发(boost::fusion 最近),此外情况 比我给出的这个例子复杂得多。
这里有 gcc 的某种选项,或任何其他软件 可以让我最好在编译时检测到此类问题,但是 即使运行时也总比没有好?
谢谢,
克林顿
最佳答案
我几个月前在 clang-dev 邮件列表上提交了这样的案例,但当时没有人有时间处理它(不幸的是,我也没有)。
Argyrios Kyrtzidis 目前正在研究它,这是他对此事的最新更新(格林威治标准时间 11 月 30 日 23 点):
I reverted the previous commit, much better fix in http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20101129/036875.html. e.g. for
struct S { int x; };
int &get_ref() { S s; S &s2 = s; int &x2 = s2.x; return x2; }
we get
t3.cpp:9:10: warning: reference to stack memory associated with local variable 's' returned
return x2;
^~
t3.cpp:8:8: note: binding reference variable 'x2' here
int &x2 = s2.x;
^ ~~
t3.cpp:7:6: note: binding reference variable 's2' here
S &s2 = s;
^ ~
1 warning generated.
之前的尝试未能通过自托管测试,所以我希望这次尝试能够通过。我很高兴 Argyrios 无论如何都在调查它:)
诚然,它还不完美,因为这是一个非常复杂的问题(在某种程度上让我想起了指针别名),但这仍然是朝着正确方向迈出的重要一步。
你能针对这个版本的 Clang 测试你的代码吗?我很确定 Argyrios 会感谢反馈(无论是否检测到)。
关于c++ - 如何在编译或运行时检测对临时问题的 const 引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4320618/