Cli*_*ton 8 c++ reference class temporary
我最近发现我的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;
}
Run Code Online (Sandbox Code Playgroud)
输出:1000
我希望这个程序输出123(在get_x()中设置xyzn的值)但是"Big b"的创建会覆盖临时Z.结果,对象Y中对临时Z的引用现在被覆盖了大b,因此输出不是我所期望的.
当我使用选项"-Wall"使用gcc 4.5编译此程序时,它没有给出任何警告.
修复显然是从类Y中的成员Z中删除引用.但是,通常类Y是我尚未开发的库(最近的boost :: fusion)的一部分,此外情况要复杂得多比我给出的这个例子.
这有一些gcc的选项,或者任何其他允许我在编译时检测这些问题的软件,但即使运行时也会比什么都好?
谢谢,
克林顿
几个月前,我在 clang-dev 邮件列表上提交了此类案例,但当时没有人有时间处理它(不幸的是,我也没有时间)。
Argyrios Kyrtzidis 目前正在研究这个问题,以下是他对此事的最新更新(格林威治标准时间 11 月 30 日 23 点):
我恢复了之前的提交,在 http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20101129/036875.html中有更好的修复。例如对于
struct S { int x; };
int &get_ref() { S s; S &s2 = s; int &x2 = s2.x; return x2; }
Run Code Online (Sandbox Code Playgroud)
我们得到
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.
Run Code Online (Sandbox Code Playgroud)
之前的尝试未能通过自托管测试,所以我希望这次尝试能够通过。无论如何,我很高兴阿吉里奥斯正在研究它:)
诚然,它还不完美,因为这是一个需要解决的相当复杂的问题(在某种程度上让我想起了指针别名),但这仍然是朝着正确方向迈出的一大步。
您可以针对此版本的 Clang 测试您的代码吗?我很确定阿吉里奥斯会欣赏您的反馈(无论是否被检测到)。