Leo*_*Leo 12 c unsigned gcc 32bit-64bit
情况:
我有一段代码在编译为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
Run Code Online (Sandbox Code Playgroud)
用-m32代码编译时编译.在没有-m32它的情况下进行编译会产生段错误.segfault的原因是(v >> 8) - p[0]被解释unsigned int为64位编译时,"负"结果将被关闭.
根据这个问题,C99标准说明如下:
6.2.5c9:A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.
由此看来,unsigned减去unsigned总是会产生unsigned与64位情况一致的输出.这似乎不会发生在32位的情况下,这是我觉得非常奇怪.
任何人都可以解释32位情况下发生的事情吗?
Die*_*Epp 14
在这两种情况下,你得到一个非常大的数字,因为unsigned int包裹,但在32位的情况下,指针算术也包裹,所以它取消了.
为了执行指针运算,编译器将数组索引提升到与指针相同的宽度.因此,unsigned对于32位指针,您可以获得int与32位指针相同的结果.
例如,
char *p = (char *) 0x1000;
// always points to 0x0c00
// in 32-bit, the index is 0xfffffc00
// in 64-bit, the index is 0xfffffffffffffc00
int r = p[(int) -0x400];
// depends on architecture
// in 32-bit, the index is 0xfffffc00 (same as int)
// in 64-bit, the index is 0x00000000fffffc00 (different from int)
int r = p[(unsigned) -0x400];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1773 次 |
| 最近记录: |