相关疑难解决方法(0)

如果计数大于类型的宽度,是右移未定义的行为吗?

我刚检查了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为代码段提供以下警告,并且res67108863:

警告:右移计数> =类型的宽度

我还检查了GCC发出的汇编代码.它只是调用SHRL,而SHRL的英特尔指令文件res不是ZERO.

那么这是否意味着GCC没有在英特尔平台上实现标准行为?

c++ assembly standards gcc undefined-behavior

32
推荐指数
2
解决办法
6393
查看次数

Bitshift和整数推广?

通常,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是否被破坏,或标准是否对位移的类型提升规则有所例外?

c standards gcc bit-manipulation integer-promotion

28
推荐指数
1
解决办法
5272
查看次数

右移计数> =类型宽度或左移位数> =类型宽度

我是新手,我试图使用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)

c

4
推荐指数
1
解决办法
1136
查看次数