情况:
我有一段代码,当编译为32位时可以正常工作,但在使用gcc 4.6编译为64位后失败了。经过确定问题并阅读标准后,我仍然不太明白为什么它能在32位下工作。希望有人能解释一下发生了什么。
代码(被简化并缩减到有趣的部分):
// tbl: unsigned short *, can be indexed with positive and negative values
// v: unsigned int
// p: unsigned char *
tmp = tbl[(v >> 8) - p[0]]; // Gives segfault when not compiled with -m32
使用-m32
编译代码可以正常运行,没有使用-m32
编译代码会导致段错误。导致段错误的原因是当编译成64位时,(v >> 8) - p[0]
被解释为一个无符号整数,对于"负"结果将会偏差很大。
根据这个问题,C99标准规定如下:
6.2.5c9: 包含无符号操作数的计算永远不会溢出,因为不能由生成的无符号整数类型表示的结果将被模除比生成类型大一的数字。
从这里看来,unsigned
减去 unsigned
将始终产生一个 unsigned
输出,这与64位情况的结果一致。但在32位的情况下,似乎并非如此,这让我感到非常奇怪。
有人能解释一下32位情况发生了什么吗?