c++ - 如何在编译或运行时检测对临时问题的 const 引用?

标签 c++ class reference 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;
}

输出: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/

相关文章:

java - 类似的子类

java - JVM 如何处理引用变量?

reference - 当结构及其成员具有不同的生命周期时理解 Rust 中的引用

C++从文本文件中读取字符串并逐字保存到链表中

c++ - 如何使用 g++ 创建具有特定名称的目标文件

c# - "Special Class"到底是什么?

ruby-on-rails - 在一个 Action 中渲染不同的 View

c# - 在变量中引用函数?

从 std::exception 派生的 C++ 自定义异常未被捕获

c++ - 如何定义嵌套类并使用它