【问题标题】:What is happening here in this C++ program?在这个 C++ 程序中发生了什么?
【发布时间】:2015-12-27 02:05:05
【问题描述】:

我正在阅读这篇出色的文章Uses & Abuses of Access Rights。我不明白下面的例子。

文件:x.h

class X 
{ 
public:
  X() : private_(1) { /*...*/ }

  template<class T>
  void f( const T& t ) { /*...*/ }

  int Value() { return private_; }

private: 
  int private_; 
};

文件:break.cpp

#include "x.h"
#include <iostream>
class BaitAndSwitch
    // hopefully has the same data layout as X
{   // so we can pass him off as one
  public:
  int notSoPrivate;
};

void f( X& x )
{
  // evil laughter here
  (reinterpret_cast<BaitAndSwitch&>(x)).notSoPrivate = 2;
}
int main()
{
    X x;
    std::cout<<x.Value()<<'\n';
    f(x);
    std::cout<<x.Value()<<'\n';
}

这个程序是如何工作的?全局函数 f() 中实际发生了什么?请有人清楚地解释一下私有变量的值是如何改变的?

为什么herb sutter 说X 和BaitAndSwitch 的对象布局不能保证相同,尽管实际上它们可能总是相同? 这个程序定义好了吗?

【问题讨论】:

  • 我认为reinterpret_cast指向“错误”对象的指针会调用未定义的行为。这个 UB 可能会做你想做的事,但推理是没有意义的,依赖它是危险的。
  • 这个程序不起作用;它的行为是未定义的。任何事情都可能发生,你会看到“任何事情”的特殊实现。
  • @PravasiMeet:即使是“你的期望”也是对“任何事情”的实现,很可能是最危险的事情。
  • 为了补充@KerrekSB 所说的内容,文章多次使用了illegalundefined 这两个词。所以我认为这篇文章很清楚这是未定义的行为,因此我们不能对结果抱有任何期望。
  • 您引用的页面本身说明了发生了什么:The code in Example 3 is illegal for two reasons: a) The object layouts of X and BaitAndSwitch are not guaranteed to be the same, although in practice they probably always will be. b) The results of the reinterpret_cast are undefined, although most compilers will let you try to use the resulting reference in the way the hacker intended.

标签: c++ private encapsulation reinterpret-cast


【解决方案1】:

见 [http://en.cppreference.com/w/cpp/language/reinterpret_cast]

你基本上是在告诉编译器你的对象实际上是一个BaitAndSwitch 对象,它实际上会按照你告诉它的做:-)

【讨论】:

    【解决方案2】:

    演员阵容正在将私人区域重新映射为新结构中的公共区域。由于未设置内部结构的布局,因此无法保证此行为有效(尽管它可能是稳定的)。

    这实际上与抓住一个指针并在其中写入一些东西没有什么不同,尽管这样做是一种更精确的方式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-13
      • 1970-01-01
      相关资源
      最近更新 更多