原文链接 为什么 A + B != A - (-B) ?
代码如下:
char *A = "123456789";
unsigned B = 1;
char *X = A + B; // X: "23456789"
char *Y = A - (-B); // Y: <Bad Ptr>
如果将上面的代码编译为32位的版本, "A + B" and "A - (-B)" 是相等的,指针 X 和 Y 都指向数组的第二项。看图1 可更好地理解 "A - (-B)" 的计算过程:
图 1
但当编译成 64-bit 程序时, "A + B" 和 "A - (-B)" 是完全不同的值。"-B" 是无符号类型,等于 0xFFFFFFFFu。如图2所示, 指针减去的是0xFFFFFFFFu 这个值:
图 2
在64位系统上会出现访问超出数组范围的错误。这类错误通常发生在用32位的无符号变量存储数组,然后使用负数来引用。下面是个例子:
unsigned Index = -1;
Array[Index] = Z;
与前面的情况 一样, "Array[Index] = Z;" 在 32-bit 环境中正常工作,但在64-bit 情况 下会出错。
结论:
应避免使用无符号数据类型来存储负值。如果用来引用数组元素的变量会出现负值,应只使用有符号的数据类型,例如 "int"。或者使用 size_t 和 ptrdfiff_t。