整数提升和右移

时间:2018-08-17 15:01:15

标签: c

考虑到例如一个无符号字符将始终被提升为一个整数,我可以假设如果在移位之前不转换为无符号字符将始终是实现定义的吗?

例如:

unsigned char c = 0x0F;
unsigned int a = c >> 2;

此处 c 将被提升为int,然后再向右移动。因此,移位将由实现定义,具体取决于编译器。

正确的方法是:

unsigned int a = (unsigned char)c >> 2;

我的问题是,这句话是真的吗?

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

2 个答案:

答案 0 :(得分:4)

结果将始终得到很好的定义。

带符号类型的右移仅是实现定义的,如果该值为负。在C standard的第6.5.7p5节中,这与按位移位运算符有关:

  

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

该值也不能为负,因为整数提升保留了要提升的值的符号。从6.3.1.1p3节开始,关于整数的转换:

  

整数促销保留包括符号在内的价值。如前所述   之前,是否将“普通”字符视为已签名   实现定义的。

因此,由于确保该值是正数,因此可以很好地定义右移操作。

答案 1 :(得分:0)

6.5.7p3关于按位移位操作说:

The integer promotions are performed on each of the operands.

如果您在位移位操作的左侧(或右侧,但这并不重要)有一个subint类型,它将被提升为int

#include <stdio.h>
int main()
{
    http://port70.net/~nsz/c/c11/n1570.html#6.5.7p3
#define TPSTR(X) _Generic(X,unsigned char: "uchar", int: "int")
    unsigned char c = 0x0F;
    printf("%s\n", TPSTR(c>>2));
    printf("%s\n", TPSTR((unsigned char)c>>2));
    printf("%s\n", TPSTR((unsigned char)c>>(unsigned char)2));
}

编译并打印int int int

仅当左操作数为负值时,才将实现定义为带符号整数类型(int)的右移:

6.5.7p5

  

如果E1具有带符号的类型和负值,则结果值为   实现定义的。

相关问题