我在这里寻找理解符号扩展: http://www.shrubbery.net/solaris9ab/SUNWdev/SOL64TRANS/p8.html
struct foo {
unsigned int base:19, rehash:13;
};
main(int argc, char *argv[])
{
struct foo a;
unsigned long addr;
a.base = 0x40000;
addr = a.base << 13; /* Sign extension here! */
printf("addr 0x%lx\n", addr);
addr = (unsigned int)(a.base << 13); /* No sign extension here! */
printf("addr 0x%lx\n", addr);
}
他们声称:
------------------ 64 位:
% cc -o test64 -xarch=v9 test.c
% ./test64
addr 0xffffffff80000000
addr 0x80000000
%
------------------ 32 位:
% cc -o test32 test.c
% ./test32
addr 0x80000000
addr 0x80000000
%
我有 3 个问题:
- 什么是符号扩展?是的,我阅读了 wiki,但不明白何时会发生类型提升,符号扩展是怎么回事?
- 为什么 ffff.. 在 64 位(引用地址)?
- 当我进行类型转换时,为什么没有符号扩展?
编辑: 4.为什么32位系统没有问题?
最佳答案
<<
的左操作数运营商进行标准促销,因此在您的情况下它被提升为 int
- 到目前为止,一切都很好。接下来,int
值(value)0x4000
乘以 213,这会导致溢出并从而导致未定义的行为。然而,我们可以看到发生了什么:表达式的值现在只是 INT_MIN
,最小的可表示的 int
。最后,当您将其转换为无符号 64 位整数时,通常的模算术规则要求结果值为 0xffffffff80000000
。同样,转换为无符号 32 位整数给出值 0x80000000
.
要对无符号值执行操作,您需要使用强制转换来控制转换:
(unsigned int)(a.base) << 13
关于c - C 中的符号扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19260052/