【发布时间】:2016-05-27 15:53:08
【问题描述】:
编辑:更改了 USHRT_MAX 的值,因为它与 cmets 显示的不一致。
假设你有一个花哨的编译器,它的整数类型限制,如 limits.h 中所定义:
#define INT_MAX 2147483647 /* Typical 32-bit system value */
#define USHRT_MAX 2147483647 /* ***Edited***, original question had 2000000000 */
在我的应用程序中,我有以下代码:
unsigned short a = 1500000000;
unsigned short b = 1500000000;
unsigned short c;
c = a + b;
据我所知,最后一条指令会发生什么:
- 在
a上进行整体推广。由于int可以接受unsigned short的所有值,所以a被提升为int。 - 出于同样的原因,
b被提升为int。 - 添加发生在
int类型上。 -
int中无法表示结果。由于第 6.5/5 段的未定义行为。
我的推理正确吗?这真的会引发未定义的行为,还是我哪里出错了?请注意,我的代码仅适用于无符号类型,并且由于无符号类型的合法溢出,可能会出现对无符号整数应用模数的结果。
如果上一个问题的答案是“是的,未定义的行为”,那么这发生在符合法律要求的编译器上。那么,您能说我发布的应用程序代码不正确吗?是否所有非显式转换的小无符号整数加法都可能引发未定义的行为?
【问题讨论】:
-
最简单的方法是如果
sizeof(unsigned short) == sizeof(int)和unsigned short有一个填充位,而int没有。在这种情况下,是的,添加两个unsigned shorts 可以调用未定义的行为。 -
USHRT_MAX 2000000000在 C 中是不可能的。无符号整数的最大值必须是 2 减一的幂。见 6.2.6.2.p1 -
为什么两个相等类型的右值之间的相加需要提升?
-
@chux 重要的是
INT_MAX == USHORT_MAX是完全可能的。 -
@Rhymoid 在 C 中,所有比
int窄的类型都会在像+这样的操作之前被提升。
标签: c language-lawyer integer-promotion