Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 位移位和整数提升?_C_Gcc_Standards_Bit Manipulation_Integer Promotion - Fatal编程技术网

C 位移位和整数提升?

C 位移位和整数提升?,c,gcc,standards,bit-manipulation,integer-promotion,C,Gcc,Standards,Bit Manipulation,Integer Promotion,通常,C要求将二进制运算符的操作数提升为更高级别的操作数类型。可以利用此漏洞来避免用冗长的强制转换填充代码,例如: if (x-48U<10) ... y = x+0ULL << 40; gcc被破坏了,或者该标准对位移位的类型提升规则做了一些例外吗?所谓的常用算术转换适用于许多二进制运算符,但不是所有的。例如,它们不适用于位移位运算符、&&、| |、逗号运算符和赋值运算符。这是位移位运算符的规则: 6.5.7。。。3语义… 对每个操作数执行整数提升。结果的类型是提升的左操作

通常,C要求将二进制运算符的操作数提升为更高级别的操作数类型。可以利用此漏洞来避免用冗长的强制转换填充代码,例如:

if (x-48U<10) ...
y = x+0ULL << 40;
gcc被破坏了,或者该标准对位移位的类型提升规则做了一些例外吗?

所谓的常用算术转换适用于许多二进制运算符,但不是所有的。例如,它们不适用于位移位运算符、&&、| |、逗号运算符和赋值运算符。这是位移位运算符的规则:

6.5.7。。。3语义…
对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数的值为负或大于或等于提升后的左操作数的宽度,则行为未定义


真正的问题是,升级只适用于平台定义为
int
的任何内容。正如其他一些答案所述,位移位运算符会将左操作数提升为int。然而,此处的
int
定义为32位值。整数转换将不会升级为
long
(64位)。

不管警告如何,它仍会升级吗?(毕竟,这只是一个警告)。您不能只使用一个简短的宏来生成详细的强制转换吗?像
#define ULL(x)((unsigned long long)x)
?@Robert:不,它产生一个No op,就好像我写了一个普通的
@R…:关于你那里的typedef,请参见
stdint.h
uint64\u t
是一个64位无符号值。这对大多数平台都是可移植的。@R。我记得他们故意选择让LHS参与整数提升,而不是RHS,因为RHS上的值只能与左边类型中的位数一样大,而不会进入未定义的行为。谢谢,这就是我想要的。
int x = 1;
unsigned long long y = x << 32ULL;
warning: left shift count >= width of type