2011-10-31 49 views
2

我最近遇到了一个非常有趣的序列化方法,该方法利用未初始化变量的透明性(编译器间常见的未定义行为?)进行“高效”反序列化。用于初始化inplace对象的新放置

存储器被分配并分配一个预定值。然后使用Placement new实例化一个结构(例如复杂的就地数据结构),将未初始化的变量“初始化”为基础内存的值。 (见下面的代码)

除了被相当危险的,可能不是一个非常愉快的编码约定......我只是想知道是否有人曾经碰到过这种方法或更重要的是 - 什么叫?

class SomeClass { 
public: 
    SomeClass() {} 

    int someInt; 
}; 

int main(...) { 
    int dummy = 42; 

    int *pSomeClass = new (&dummy) SomeClass(); 
    cout << pSomeClass->someInt << endl; 
} 

这将打印出数字42 ... neato!

回答

5

这就是所谓的“依托UB”,或者在外行的话来说,“愚蠢”。

+0

我相信你是对的,但UB在哪里? –

+0

@David:'pSomeClass :: someInt'未初始化。 –

+0

虽然'struct'和'class'的布局是明确的,还是不是? –

2

我已经看到了eCos的,一个RTOS这个工作,初始化一些自己的内核对象。

正如所指出托默勒格牵伸背上之一是允许没有虚函数。 他们试图通过测试相同的尺寸sizeof(kernel object) == sizeof(variable used for initialization)

他们的代码虽然是使用C型结构来模拟的C++接口而不是使用C函数来获取C++类的成员变量的方式更加复杂/设置在C++类的变量

虽然行为,他们有一个恰好相反的结论,他们使用C++类中的值(在构造函数中设置)来填充placement new的内存。

我不建议这样做。