默认情况下对Int进行签名,这通常意味着保留高位以指示整数是否为负.查看两个补码,了解其工作原理.
这是结果:
[steven@sexy:~]% cat test.c
#include <stdint.h>
#include <stdio.h>
int main(int argc, char **argv[]) {
uint32_t uint;
int32_t sint;
int64_t slong;
uint = (((uint32_t)1)<<31) >> 31;
sint = (1<<31) >> 31;
slong = (1L << 31) >> 31;
printf("signed 32 = %d, unsigned 32 = %u, signed 64 = %ld\n", sint, uint, slong);
}
[steven@sexy:~]% ./test
signed 32 = -1, unsigned 32 = 1, signed 64 = 1
Run Code Online (Sandbox Code Playgroud)
请注意如何通过使用"unsigned"int(允许使用所有32位)或通过更大的类型来避免此问题.
在您的情况下,1表达式中的表达式是签名类型 - 因此当您将其升档31时,其符号会发生变化.然后降档导致符号位重复,最终得到一个位模式0xffffffff.
你可以像这样解决它:
int temp = (1UL << 31) >> 31;
Run Code Online (Sandbox Code Playgroud)
如果你-Wall打开了,GCC会警告这种错误.