
short int 在 64 位 Linux/macOS/Windows 上到底是几个字节?
它通常是 2 字节,不是 4,也不是 8 —— 和系统是 32 位还是 64 位无关。
C++ 标准只要求 short int 至少能表示 -32767 到 +32767(即 ≥16 位),实际长度由编译器和 ABI 决定,而非 CPU 架构位数。主流平台(GCC、Clang、MSVC)在 x86_64 和 aarch64 上都坚持用 2 字节实现 short。
- 你可以用
sizeof(short)验证:几乎总是输出2 - 不要因为指针变 8 字节就误以为整数类型也“跟着升级”
- ARM64 macOS(Apple Silicon)和 x86_64 Windows 同样遵守这个惯例
为什么 sizeof(short) ≠ sizeof(void*)?
指针大小取决于地址空间宽度(64 位系统需要 8 字节寻址),而 short 是算术类型,设计目标是提供最小的“足够用”的有符号整数,兼顾内存紧凑性和运算效率。
让 short 变成 8 字节会浪费大量内存(比如数组、结构体填充),且没带来实质好处 —— 加法、比较等操作在现代 CPU 上对 16 位和 64 位整数性能差异微乎其微。
立即学习“C++免费学习笔记(深入)”;
-
short的 ABI 约定(如 System V AMD64 ABI、Microsoft x64 ABI)明确将其定义为 16 位、2 字节 - 即使你强制用
-m32编译 32 位程序,在 64 位系统上跑,sizeof(short)还是2 - 真正随平台变化的是
long(Linux/macOS 是8,Windows 是4)和指针
什么时候真得关心 short 的大小?
主要在跨平台二进制数据交换、内存映射文件、网络协议打包、嵌入式寄存器布局这些场景下,short 的固定尺寸才成为约束条件。
比如用 write() 直接写一个 short 数组到文件,另一端用 C 或 Python struct.unpack('h*') 读取 —— 这时你依赖的就是它恰好是 2 字节、小端或大端。
- 别假设
short能存下int值:在int是 4 字节的平台,(short)65536会溢出变成0 - 结构体里混用
short和char时,注意对齐:编译器可能在后面补 1 字节使下一个int对齐到 4 字节边界 - 想绝对可控,用
int16_t(来自<cstdint></cstdint>)代替short,它保证是带符号 16 位整数
常见误解和编译器警告陷阱
有人看到 sizeof(void*) == 8 就改写 short 相关逻辑,结果引入越界或截断 bug;还有人把 short* 强转成 int* 去“加速读取”,这在绝大多数架构上会触发未定义行为(unaligned access 或 strict aliasing 违反)。
- Clang/GCC 开启
-Wshorten-64-to-32(或-Wconversion)会警告把size_t或指针转成short—— 这类转换极大概率丢数据 - MSVC 默认不报这类警告,需手动加
/W4并留意C4244 -
std::vector<short></short>的内存布局是连续的 2 字节块,但迭代器递增仍是按sizeof(short)跳,不是按指针大小跳
真正容易被忽略的点是:ABI 固化了 short 的尺寸,但标准没固化它的符号位行为(理论上可实现为 sign-magnitude,尽管现实中全是 two's complement);如果你在极端冷门平台或自研工具链上工作,sizeof(short) 仍值得实测。










