情况:
我有一段代码在编译为 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
在没有它的情况下编译时会出现段错误。段错误的原因是(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 位的情况下发生了什么?