short在struct中占4字节是因对齐填充所致:前面为int时前补2字节,后面为int时后补2字节,如struct{int a;short b;}大小为8而非6;实际对齐由alignof(short)决定(通常为2),但struct整体对齐取成员最大alignof值。

short 在 struct 里为什么占了 4 字节?
因为默认对齐方式按最大成员对齐,short 本身是 2 字节,但若它前面是 int(通常 4 字节),编译器会在 short 前补 2 字节填充,让它地址能被 2 整除;而如果后面跟着 int,又可能在 short 后补 2 字节,确保下一个 int 地址对齐到 4 字节边界。
常见错误现象:sizeof(struct { int a; short b; }) 返回 8 而不是 6 —— 就是因为 b 后面被塞了 2 字节 padding。
- 对齐单位不是固定值,由
alignof(short)决定(通常是 2) - 但整个 struct 的对齐要求取各成员
alignof的最大值,所以即使只有short,struct 对齐也是 2 - 实际布局受编译器默认对齐设置影响,比如
#pragma pack(1)可禁用 padding,但会牺牲性能
怎么查一个 short 实际的对齐要求?
用 alignof 运算符最直接:alignof(short) 在绝大多数平台返回 2,但它不是语言强制,而是实现定义。x86-64 Linux/GCC/Clang 下基本稳定,但嵌入式平台(如某些 ARM Cortex-M)可能因 ABI 要求不同而返回 1 或 4。
使用场景:写跨平台序列化代码时,不能假设 short 总是“自然对齐”,尤其当结构体要 memcpy 到网络或文件时。
立即学习“C++免费学习笔记(深入)”;
-
alignof(short)是编译期常量,可直接用于static_assert - 别用
sizeof推断对齐 ——sizeof(short)是 2,但对齐可能是 4(如某些旧 MSVC 模式) - 检查方式:打印
offsetof(struct { char c; short s; }, s),结果为 2 表示没额外填充,为 4 表示有对齐扩张
gcc/clang 里改 short 对齐会影响什么?
用 __attribute__((aligned(N))) 强制提升 short 对齐(比如 N=8),会让它占用更多空间、并可能拖慢访问——CPU 读 8 字节对齐的 2 字节数据,通常不会报错,但可能触发额外内存事务或 cache line 分裂。
性能影响比想象中明显:在 tight loop 里频繁读写这类字段,L1d cache 命中率可能下降,尤其当 struct 数组被连续遍历时。
- 强制对齐只影响该变量/字段,不影响同 struct 内其他成员的对齐计算
-
__attribute__((packed))会取消所有 padding,但可能导致short出现在奇数地址,ARMv7 及更早架构上触发 unaligned access fault - Clang 的
-Waddress-of-packed-member能提醒你取了 packed struct 里short的地址——这种指针解引用可能不安全
struct 里 short 放前面还是后面更省空间?
放前面通常更好。比如 struct { short a; int b; char c; } 占 12 字节(a:2 + pad:2 + b:4 + c:1 + pad:3),而 struct { int b; short a; char c; } 占 16 字节(b:4 + a:2 + pad:2 + c:1 + pad:3)。差 4 字节,数组放大后很可观。
这不是玄学,是填充字节位置依赖字段顺序的结果。编译器不会重排字段(C++ 标准禁止),所以顺序就是布局。
- 按大小降序排列字段(
double→int→short→char)一般最紧凑 - 但别为了省几字节牺牲可读性——比如把标志位
bool valid硬塞到一堆short中间,维护时容易出错 - 用
offsetof和sizeof验证实际布局,别靠脑补
short 因为太小,反而最容易被当成“无害”忽略掉。







