我正在尝试了解 static_cast
和 reinterpret_cast
。
如果我是正确的,标准 (9.2.18) 表示 pod 数据的 reinterpret_cast
是安全的:
A pointer to a POD-struct object, suitably converted using a
reinterpret_cast
, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. [ Note: There might therefore be unnamed padding within a POD-struct object, but not at its beginning, as necessary to achieve appropriate alignment. — end note ]
我的问题是如何严格解释这一点。例如,布局兼容性是否足够?如果不是,为什么不呢?
对我来说,以下示例显示了一个严格的“仅 POD 有效”解释似乎是错误的示例。
class complex_base // a POD-class (I believe)
{
public:
double m_data[2];
};
class complex : public complex_base
{ //Not a POD-class (due to constructor and inheritance)
public:
complex(const double real, const double imag);
}
double* d = new double[4];
//I believe the following are valid because complex_base is POD
complex_base& cb1 = reinterpret_cast<complex_base&>(d[0]);
complex_base& cb2 = reinterpret_cast<complex_base&>(d[2]);
//Does the following complete a valid cast to complex even though complex is NOT POD?
complex& c1 = static_cast<complex&>(cb1);
complex& c2 = static_cast<complex&>(cb2);
此外,如果 complex_base::m_data
受到保护(意味着 complex_base
不是 pod),有什么可能会破坏? [编辑:以及我如何保护自己/检测此类破损]
在我看来,布局兼容性应该足够了——但这似乎不是标准所说的。
编辑: 感谢您的回答。他们还帮我找到了这个, http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm
最佳答案
I believe the following are valid because complex_base is POD
你错了。 d[0]
不引用 complex_base
对象的第一个成员。因此,它的对齐方式对于 complex_base
对象可能不够好,因此这样的转换是不安全的(并且您引用的文本不允许)。
Does the following complete a valid cast to complex even though complex is NOT POD?
cb1
和 cb2
不指向 complex
类型对象的子对象,因此 static_cast
产生未定义的行为。引用C++03的5.2.9p5
If the lvalue of type "cv1 B" is actually a sub-object of an object of type D, the lvalue refers to the enclosing object of type D. Otherwise, the result of the cast is undefined.
仅将所涉及的类型组合在一起是不够的。文本讨论了指向 POD 结构对象的指针和引用某个子对象的左值。 其他 complex 和 complex_base 都是标准布局对象。 C++0x 规范说,而不是你引用的文本:
POD-ness 要求是否过于严格?
这是一个不同的问题,与您的示例代码无关。是的,要求 POD-ness 太严格了。在 C++0x 中,这一点得到认可,并给出了更宽松的新要求,即“标准布局”。根据 C++0x 的定义,我确实认为 complex
和 complex_base
都是标准布局类。 C++0x 规范说,而不是你引用的文本:
A pointer to a standard-layout struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa.
我将其解释为允许将指针转换为 double
,它实际上指向 complex
成员(继承成员),转换为 复杂*
。标准布局类是没有包含非静态数据的基类,或者只有一个包含非静态数据的基类的类。因此有一个唯一的“初始成员”。
关于c++ - 几乎 pod 数据的 reinterpret_cast(布局兼容性是否足够),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5060879/