签名字符到无符号Int转换的标准C ++行为

时间:2016-12-07 07:26:58

标签: c++ implicit-conversion c++03

我快速浏览了C ++ 03标准,但仍无法判断这种行为是否得到保证:

signed char cNegOne=-1; //char is 8bits
unsigned int a=cNegOne; //int is 32 bits in my Windows system
printf("0x%x\n",a);

结果是:

0xffffffff

VC ++在32位Windows中提供0xffffffff。但我的假设是转换可能以两种方式发生:

1)8位有符号字符-1首先直接转换为8位无符号值,即二进制11111111或十进制255,然后加宽为32位无符号整数,给出255(0xff)。

2)8位有符号字符-1被签名扩展为32位有符号整数,给出0xffffffff,然后重新解释为32位无符号整数。

显然第二种方式在这里使用。但为什么会这样呢?在标准中,我找不到任何谈论这个的事情。具体是实施吗?

编辑:来自C ++ 03第4章的原始文本

标准转化是为内置类型定义的隐式转化。第4条列举了全套此类转换。标准转换序列是按以下顺序的一系列标准转换:

- 来自以下集合的零或一次转换:左值到右值的转换,数组到指针的转换以及函数到指针的转换。

- 来自以下设置的零次或一次转换:整数促销,浮点促销,积分转换,浮点转换,浮点积分转换,指针转换,指向成员转换的指​​针,以及 布尔转换。

- 零或一个资格转换。

注意保证顺序是l到rvalue转换(等)在设置整数促销/转换之前发生,但这并不意味着必须在转换之前发生整体推销 - 它们只是在同一组中。或者我的解释是否正确?

1 个答案:

答案 0 :(得分:4)

在C和C ++中执行整数运算时,第一步是整数提升。签名的字符和短裤成为签名的; unsigned chars和short成为无符号的整数。即使您将两条短片放在一起,这也是正确的:操作本身是在整数上执行的,而不是短暂的。

因此,当您考虑整数转换时,请考虑促销,然后改变签名。在C ++标准中,这两个步骤被描述为一个。也就是说,单独的整体提升在技术上不会发生,但如果目标类型比源类型更宽,则更改签名的效果与在签名更改之前显式提升时发生的效果相同。基本规则是结果必须是输入模2 ^ n,其中n是输出类型的位数。对于输入-1和32位输出类型,这意味着输出为2 ^ 32 - 1。