c oracle 7.3.3版本,7.3.3 符号扩展

7.3.3 符号扩展

转换到 64 位编译环境时,经常会遇到符号扩展问题,这是因为类型转换和提升规则有些模糊。为防止出现符号扩展问题,请使用显式强制类型转换以取得预期结果。

要了解出现符号扩展的原因,了解 ISO C 的转换规则会有所帮助。可能会导致 32 位和 64 位编译环境之间大多数符号扩展问题的转换规则在以下操作过程中有效:

整型提升

无论有无符号,均可在调用整型的任何表达式中使用 char、short、枚举类型或位字段。

如果一个整型可以容纳初始类型的所有可能值,则值转换为整型;否则,值转换为无符号整型数。

带符号整型数和无符号整型数之间的转换

当一个带负号的整数被提升为同一类型或更长类型的无符号整型数时,它首先被提升为更长类型的带符号等价值,然后转换为无符号值。

以下示例被编译为 64 位程序时,即使 addr 和 a.base 均为无符号类型,addr 变量仍可成为带符号扩展变量。

%cat test.c

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);

}

发生此符号扩展的原因是按以下方式应用了转换规则:

由于整型提升规则,a.base 将从无符号 int 转换为 int。因此,表达式 a.base << 13 的类型为 int,但是未发生符号扩展。

表达式 a.base << 13 的类型为 int,但是在赋值给 addr 之前,由于带符号和无符号整型数提升规则,会转换为 long,然后转换为无符号 long。从 int 转换为 long 时,会发生符号扩展。

% cc -o test64 -xarch=v9 test.c

% ./test64

addr 0xffffffff80000000

addr 0x80000000

%

如果将同一示例编译为 32 位程序,则不显示任何符号扩展:

cc -o test test.c

%test

addr 0x80000000

addr 0x80000000

有关转换规则的详细讨论,请参见 ISO C 标准。此标准中还包含对普通算术转换和整型常量有用的规则。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值