考虑到例如一个 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 的数据类型进行任何转换都将是实现定义的?
结果将永远是明确的。
如果值为负,则签名类型的右移仅是实现定义的。这在C 标准的第 6.5.7p5 节中关于按位移位运算符指定:
E1 >> E2 的结果是 E1 右移 E2 位位置。如果 E1 具有无符号类型或者如果 E1 具有有符号类型和非负值,则结果的值是 E1 / 2 E2的商的整数部分。如果 E1 具有有符号类型和负值,则结果值是实现定义的。
该值也不能为负数,因为整数提升保留了被提升值的符号。来自关于整数转换的第 6.3.1.1p3 节:
整数提升保留值,包括符号。如前所述,“普通”字符是否被视为有符号是实现定义的。
因此,因为该值保证为正,所以右移操作被很好地定义。