这是一段我不太明白的代码:
#include <iostream>
struct Ptr {
void* ptr
#ifdef WAT
= 0
#endif
;
};
struct A {
Ptr ptr;
int d;
};
struct B : public A { int e; };
static_assert(sizeof(A) == 16, "ok");
static_assert(sizeof(B) == 24, "wat");
int main() {
// This code is just to show that the classes are actually used
// by the program
B b;
b.ptr.ptr = new int{};
b.d = b.e = 42;
std::cout << b.ptr.ptr << " " << b.d << " " << b.e << std::endl;
}
我希望对象大小与void* ptr
字段的初始化程序无关。但是,是否使用-DWAT
编译此代码还是有区别的,至少在clang中:使用-DWAT
,sizeof(B)
实际上是16,这与我的直觉相反:{ {3}}
这种行为是否有合理的直觉?我知道对象布局没有很多保证,但是有没有方法在初始化程序存在的情况下强制执行“默认”行为?
更新:看起来,布局算法在具有显式默认构造函数/字段初始化器的对象之间有所不同,而没有(POD,普通旧数据类型)。但是,我仍然不完全了解逻辑。