整数提升c

时间:2017-06-09 10:18:44

标签: c integer-overflow integer-promotion

假设我有一台32位计算机。

我知道在整数提升期间表达式转换为:\

  • int如果原始类型的所有值都可以用int
  • 表示
  • unsigned否则

请您解释一下下面这个表达式会发生什么?一般来说,排名如何在这里工作?

第一个片段:

si16  x, pt;
si32  speed;
u16 length;
x = (speed*pt)/length;

第二个:

x = pt + length;

编辑:

si16表示signed short(大小为16位),si32位表示signed int(大小为32位),u16表示unsigned short(大小16)

我发现以下链接已经非常清楚地描述了这个问题: Implicit type conversion

具体来说,阅读 Lundin 的答案,非常有帮助!

2 个答案:

答案 0 :(得分:3)

整数提升规则,正确引用C11 6.3.1.1:

  

如果int可以表示原始类型的所有值(限制为   通过宽度,对于位字段),该值被转换为int;   否则,它将转换为unsigned int。这些被称为   整数促销。所有其他类型的整数不变   促销。

其中"否则,它被转换为unsigned int"实际上只在一个特定的特殊情况下使用,即较小的整数类型unsigned shortunsigned int具有相同的大小。在这种情况下,它将保持未签名。

除了这种特殊情况之外,所有小整数类型总是会被提升为(签名)int,无论其签名如何。

假设32位int,则:

 x = (speed*pt)/length;

speed已签署32,不会升级。 ptr将整数提升为int(已签名为32)。 speed*ptr的结果将为int类型。

length会将整数提升为int。该部门将使用int类型的操作数执行,结果类型将为int

结果将转换为已签名的16,因为它已分配给x(分配期间的左值转换)。

x = pt + length;类似,此处+的两个操作数将在添加之前升级为int,之后结果将转换为带符号16。

答案 1 :(得分:0)

整数提升规则在6.3.1.8 Usual arithmetic conversions中定义。

1.  si16  x, pt;
    si32  speed;
    u16 length;
    x = (speed*pt)/length;

2. x =  pt + length;

排名有效地表示limits.h中CAM定义的类型的位数。标准规定CAM中较低等级的类型对应于实施中较低等级的类型。

对于您的代码,

speed*pt

是int32和int 16之间的乘法,这意味着它在

中被转换
speed*(int16=>int32)pt

,结果tmp1将为int32

接下来,它将继续

tmp1_int32 / length

长度将从uint16转换为int32,因此它将计算tmp2所以:

tmp1_int32 / (uint16=>int32) length

,结果tmp2的类型为int32。

接下来它会评估一个赋值表达式,左边是16位,右边是32,所以它会剪切结果:

x = (int32=>int16) tmp2_int32

您的第二个案例将被评估为

x = (int32=>int16) ( (int16=>int32) pt + (uint16=>int32) length )

如果运算符的两个操作数都小于int的等级,则CAM允许在操作未溢出时添加两种类型,然后将结果转换为整数。

换句话说,可以在

中转换INT16 + INT16
 INT16+INT16

 (int32=>int16) ((int16=>int32) INT16 + (int16=>int32)INT16)

如果可以在没有溢出的情况下完成添加。