【发布时间】: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 所说的内容,文章多次使用了illegal 和undefined 这两个词。所以我认为这篇文章很清楚这是未定义的行为,因此我们不能对结果抱有任何期望。
-
您引用的页面本身说明了发生了什么:
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