short→int是安全的隐式转换,因值保留和符号扩展;int→short是有损显式转换,溢出导致未定义行为,需先验证范围。

short 和 int 在 C++ 中属于兼容类型,但这种兼容性是有条件的、单向的,且主要体现在有符号窄类型向宽类型的隐式提升上。
short → int 是安全的隐式转换
只要 short 值在 int 的表示范围内(即 -32768 到 32767),赋值或参与运算时会自动提升为 int,不会丢失精度或引发未定义行为。这是因为:
- C++ 标准规定:有符号整数从窄类型到宽类型的转换是“值保留”的,编译器执行符号扩展(sign extension)
- 主流平台中 short 是 16 位、int 是 32 位,所有合法 short 值都能无损映射到 int
- 例如:
short s = -1; int i = s;得到i == -1,二进制补码正确扩展
int → short 属于有损转换,必须显式操作
将 int 赋给 short 可能溢出,C++ 视为未定义行为(UB)。即使数值看似在范围内,编译器也不保证截断逻辑一致:
- 不加检查直接写
short s = some_int;风险极高,尤其在优化开启后行为不可预测 - 安全做法是先验证范围:
if (x >= SHRT_MIN && x (x); - 若需强制截断(如音频采样),应通过无符号中间类型控制:
s = static_cast<short>(static_cast<uint16_t>(x) & 0xFFFF);</uint16_t></short>
混用时容易触发隐式提升陷阱
看似简单的表达式可能隐藏类型变化,影响结果和性能:
-
short a = 32767, b = 1; auto c = a + b;→c类型是int,不是short -
short c = a + b;编译通过,但运行时发生溢出(32768 → -32768),属未定义行为 - 函数重载中
void f(int)和void f(short)并存时,字面量f(42)总匹配int版本,而f('x')可能意外调用short版
跨平台与可移植性建议
short 的大小不固定(标准仅要求 ≥16 位),int 更依赖 ABI;真正需要确定宽度时,应优先使用标准固定宽度类型:
- 协议字段、内存布局敏感场景,用
int16_t/int32_t替代short/int - 包含
<cstdint></cstdint>,并用static_assert(sizeof(int16_t) == 2);显式确认 - 避免用
short做模板参数或 auto 推导起点,因其在不同上下文中可能被静默提升











