C89与C99隐式转换规则疑问:short相乘未显式转换为何结果正确
问题解答
核心原因是你遗漏了C语言隐式转换规则中整数提升这一前置步骤,它是所有算术运算执行前的强制操作,不属于你列举的4种常规算术转换场景。
- 整数提升的规则如下:
在执行任何算术运算前,所有类型等级低于int的整数类型(包括char、short、有符号/无符号位域等),只要其取值范围可以被int完整容纳,就会被隐式转换为int类型;如果无法被int容纳,则转换为unsigned int类型,该转换和两个操作数是否为同类型无关。
第一个代码运行正确的原因
你代码中的b和c都是short类型,符合整数提升的触发条件:
执行
b * c前,两个short类型的操作数会先被转换为int类型,实际执行的是两个int值的乘法,运算结果也是int类型。
目前绝大多数通用计算机平台的int都是32位,最大值为2^31-1=2147483647,远大于10000*150的结果150000,不会发生溢出,赋值给int类型的变量a自然能得到正确结果。
两个代码结果不同的原因
你提到的第二个代码的场景和第一个有本质区别:
变量
j本身就是int类型,不需要触发整数提升,j * j的运算直接在int类型下执行,运算完成后才会做强制类型转换为long。
如果是在int为16位的嵌入式平台,int的最大值仅为32767,1000*1000的结果1000000远超出该范围,运算过程中就已经发生了有符号整数溢出(属于未定义行为),后续的类型转换无法修正已经溢出的错误结果。
你可以做极端场景验证:如果是在short为16位、int也为16位的老式16位单片机平台上运行你的第一个代码,也会得到溢出后的错误结果。
内容的提问来源于stack exchange,提问作者user14479570
相关产品推荐
相关产品推荐

