C 位移位和整数提升?
通常,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语义… 对每个操作数执行整数提升。结果的类型是提升的左操作
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