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

gcc/clang与MSVC2015多继承空类时的内存填充规则差异解析

多继承空类的大小差异:C++标准依据解析

先把你的测试代码格式化一下,方便看:

#include <cstdint>
using namespace std;

class Empty1 {};
static_assert(sizeof(Empty1) == 1, "Expected size of 1 for Empty1");

class Empty2 {};
static_assert(sizeof(Empty2) == 1, "Expected size of 1 for Empty2");

class Empty3 : Empty2, Empty1 {};
static_assert(sizeof(Empty3) == 1, "Expected size of 1 for Empty3");

你碰到的GCC/Clang和MSVC2015的行为差异,核心原因是空基类优化(Empty Base Class Optimization, EBCO)的实现策略不同,而C++标准明确允许这种差异存在。

标准条款依据

在C标准的**[class.size]**章节(不同版本编号略有调整:C11为9.2.15,C++17及之后是10.3.2)里,有明确规定:

类的大小不得小于1字节。如果一个类是空的(无静态数据成员、无虚函数、无虚基类),那么当它作为基类时,实现可以选择不为其分配额外存储空间——只要不会和其他基类或成员的存储空间重叠即可。

划个重点:这是可选优化,不是强制要求。标准只规定了空类本身的大小至少为1,但空基类是否要占存储空间,完全由编译器自行决定。

为什么不同编译器表现不同

  • GCC和Clang做了更激进的EBCO:哪怕多继承多个空基类,它们也会把这些空基类的存储空间合并,只保留1字节的最小大小,所以sizeof(Empty3)是1。
  • MSVC2015的EBCO实现比较保守:在多继承多个空基类的场景下,它没有合并存储空间,每个空基类都占1字节,所以sizeof(Empty3)会是2,导致你的static_assert触发失败。

补充一句:MSVC后续版本(比如2017及之后)已经改进了EBCO的实现,多继承空基类时也能做到大小为1,但2015版本的行为确实符合标准的允许范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:53:37