我刚检查了C++标准.看来以下代码不应该是未定义的行为:
unsigned int val = 0x0FFFFFFF;
unsigned int res = val >> 34; // res should be 0 by C++ standard,
// but GCC gives warning and res is 67108863
Run Code Online (Sandbox Code Playgroud)
并从标准:
E1 >> E2的值是E1右移E2位位置.如果E1具有无符号类型或者E1具有有符号类型和非负值,则结果的值是E1/2 ^ E2的商的整数部分.如果E1具有有符号类型和负值,则生成的值是实现定义的.
根据标准,由于34不是负数,因此变量res将为0.
GCC为代码段提供以下警告,并且res是67108863:
警告:右移计数> =类型的宽度
我还检查了GCC发出的汇编代码.它只是调用SHRL,而SHRL的英特尔指令文件res不是ZERO.
那么这是否意味着GCC没有在英特尔平台上实现标准行为?
通常,C要求将二元运算符的操作数提升为更高级别操作数的类型.这可以被利用来避免用详细的强制转换填充代码,例如:
if (x-48U<10) ...
y = x+0ULL << 40;
Run Code Online (Sandbox Code Playgroud)
等等
但是,我发现,至少对于gcc,这种行为不适用于位移.即
int x = 1;
unsigned long long y = x << 32ULL;
Run Code Online (Sandbox Code Playgroud)
我希望右手操作数的类型可以促使左手操作数被提升,unsigned long long以便移位成功.但相反,gcc会打印一个警告:
warning: left shift count >= width of type
Run Code Online (Sandbox Code Playgroud)
gcc是否被破坏,或标准是否对位移的类型提升规则有所例外?
我是新手,我试图使用UDP发送64位值.
int plugin(unsigned char *Buffer) {
static const uint8_t max_byte = 0xFF;
uint8_t id[8];
id[0] = (uint8_t)((Buffer[0]) & max_byte);
id[1] = (uint8_t)((Buffer[1] >> 8) & max_byte);
id[2] = (uint8_t)((Buffer[2] >> 16) & max_byte);
id[3] = (uint8_t)((Buffer[3] >> 24) & max_byte);
id[4] = (uint8_t)((Buffer[4] >> 32) & max_byte);
id[5] = (uint8_t)((Buffer[5] >> 40) & max_byte);
id[6] = (uint8_t)((Buffer[6] >> 48) & max_byte);
id[7] = (uint8_t)((Buffer[7] >> 56) & max_byte);
}
Run Code Online (Sandbox Code Playgroud)
我收到错误右移计数> =类型的宽度.我尝试过其他方式
int plugin(unsigned char *Buffer) {
uint64_t id = (Buffer[0] …Run Code Online (Sandbox Code Playgroud)