You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C++中派生结构体大小会因基类成员是否初始化而不同?

基类成员默认初始化引发派生类大小差异的原因

先看问题中的代码:

#include <cstdint>

struct B1 { int x; short y = 0; };
struct D1 : B1 { short z; };
struct B2 { int x; short y; };
struct D2 : B2 { short z; };
static_assert(sizeof(D1) == sizeof(D2));

在GCC 14.2和Clang 18.0.1中,这段代码编译失败,编译器提示断言条件sizeof(D1) == sizeof(D2)不成立,实际大小对比为8 == 12。

差异原因解析

这种现象的核心是C++标准对平凡可复制类型的布局规则,以及默认成员初始化器对类平凡性的影响:

  1. 类的平凡性判定

    • B2没有默认成员初始化器,所有成员都是基础类型,编译器生成的默认构造函数、析构函数、赋值运算符都是平凡的,因此B2属于平凡可复制类型。这类类型的内存布局必须严格连续,保证能通过memcpy等低级内存操作安全复制。
    • B1中的short y = 0是默认成员初始化器,这会让编译器生成的默认构造函数变为非平凡(需要自动初始化y),因此B1不属于平凡可复制类型。
  2. 派生类布局的优化限制

    • 针对平凡可复制的基类B2:编译器不能将派生类D2的成员z放入B2的尾部填充空间。B2的布局是int x(4字节)+short y(2字节),为满足int的4字节对齐要求,尾部会填充2字节,总大小8字节。D2的z必须放在B2内存之后,占用2字节,之后再填充2字节以满足4字节对齐,最终D2总大小为12字节。
    • 针对非平凡可复制的基类B1:编译器不受平凡可复制类型的布局限制,可以做优化,将D1的成员z直接放入B1的尾部填充空间中。因此D1的总大小和B1一致,为8字节。

内容的提问来源于stack exchange,提问作者MarkB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 11:12:31