整数提升和右移

Fre*_*rik 3 c

考虑到例如一个 unsigned char 将总是被提升为一个 int 我可以假设如果我在转换结果之前不强制转换为 unsigned char 将始终是实现定义的吗?

例如:

unsigned char c = 0x0F;
unsigned int a = c >> 2;
Run Code Online (Sandbox Code Playgroud)

这里c在向右移动之前将被提升为 int。因此,转换将是实现定义的,具体取决于编译器。

正确的方法是:

unsigned int a = (unsigned char)c >> 2;
Run Code Online (Sandbox Code Playgroud)

我的问题是,这种说法是否正确:

如果不转换为无符号类型,则对任何小于 int 的数据类型进行任何转换都将是实现定义的?

dbu*_*ush 5

结果将永远是明确的。

如果值为负,则签名类型的右移仅是实现定义。这在C 标准的第 6.5.7p5 节中关于按位移位运算符指定:

E1 >> E2 的结果是 E1 右移 E2 位位置。如果 E1 具有无符号类型或者如果 E1 具有有符号类型和非负值,则结果的值是 E1 / 2 E2的商的整数部分。如果 E1 具有有符号类型和负值,则结果值是实现定义的。

该值也不能为负数,因为整数提升保留了被提升值的符号。来自关于整数转换的第 6.3.1.1p3 节:

整数提升保留值,包括符号。如前所述,“普通”字符是否被视为有符号是实现定义的。

因此,因为该值保证为正,所以右移操作被很好地定义。

  • 如果原始类型为无符号类型,则否。第 6.3.1.1p2 节指出“*如果一个 int 可以表示原始类型的所有值(受宽度限制,对于位域),则将该值转换为 int;否则,将其转换为 unsigned int *”。因此,如有必要,提升的类型可以是 `unsigned int`。 (2认同)