c++ - 几乎 pod 数据的 reinterpret_cast(布局兼容性是否足够)

标签 c++ reinterpret-cast static-cast

我正在尝试了解 static_castreinterpret_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?

cb1cb2 不指向 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/

相关文章:

C++ static_cast - 更安全的方式。为什么?

c++ - static_cast 被滥用了吗?

c++ - 您可以将 "this"静态转换为基类构造函数中的派生类,然后稍后使用结果吗?

c++ - 如何使用基于范围的 for 循环在 C++ 中迭代可变的重复 Proto 字段?

c++ - Win32 GDI 画一个圆?

c++ - 使用 reinterpret_cast 将数据从 std::vector<double> reshape 为指定维度的 double**

c++ - dynamic_cast 返回相同的对象类型失败,具有多重继承和中间变量

c++ - 使用 Python 的 Matplotlib 绘制在 C++ 程序中生成的数据

c++ - Qt 更新()不起作用

C# 将 bool 重新解释为 byte/int(无分支)