为什么对基类子对象有限制?

8 c++ types base-class

3.9/2:

对于普通可复制类型T的任何对象(基类子对象除外),无论对象是否保持类型T的有效值,构成对象的基础字节(1.7)都可以复制到char或者数组中.无符号的字符.

3.9/3:

对于任何平凡复制的类型T,如果两个指针至T指向不同T对象OBJ1和OBJ2,其中既不 OBJ1 也不 OBJ2是一个 基类的子对象,如果OBJ1被复制到OBJ2底层字节(1.7)组成,OBJ2应随后保持与obj1相同的值.

我正式理解这些规则,但我感兴趣的是这些限制的重点是什么?

小智 9

基类子对象可能在派生类使用的末尾有填充.鉴于两个班级,

struct A {
  int a;
  char b;
};
struct B : A {
  char c;
};
Run Code Online (Sandbox Code Playgroud)

这完全有可能sizeof(A) == sizeof(B).如果它们是相同的,那么如果你只是简单地memcpy用来复制A子对象就应该清楚事情会破坏:你将无法阻止读取甚至覆盖该c值.

您的实现可能会也可能不会重复使用这样的填充.设计重复使用填充的ABI的正当理由恰恰是处理不正确地memcpy用于此类子对象的代码.

注释给出了一个空基类的例子.这是当前实现很可能重用基类的一个字节的一种特殊情况,但它不是唯一允许的时间.