如何在编译或运行时检测const引用临时问题?

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的选项,或者任何其他允许我在编译时检测这些问题的软件,但即使运行时也会比什么都好?

谢谢,

克林顿

Mat*_* M. 2

几个月前,我在 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 测试您的代码吗?我很确定阿吉里奥斯会欣赏您的反馈(无论是否被检测到)。