3

在指针算术的情况下,整数是否会自动转换为其有符号变体?如果是,为什么?

假设我这样做

int *pointer; 
int *pointerdiff;
unsigned int uiVal = -1;

pointerdiff = pointer + uiVal // Pointer will contain valid address here.

其中 pointer 是指向 int 的指针,uiVal 初始化为 -1,然后我发现指针中的地址减 4。为什么这里不考虑 -1 的无符号值?

4

3 回答 3

8

看起来你的指针溢出了。

让我们做一些数学运算。假设您在 32 位机器上,并且您的指针被初始化为0x 12 34 56 78. 然后我们将一个 unsigned int 变量初始化为-1,即0x FF FF FF FF。因为它是一个无符号整数,所以-1溢出并且实际上表示4 294 967 295.

您的指针指向一个整数 ( int*),因此每个增量实际上都会将地址增加sizeof int1,在标准 x86 机器上为 4。所以我们实际上是在添加0x 03 FF FF FF FC(即0x FF FF FF FF * 4)。

现在让我们将两者相加。

  0x 00 12 34 56 78
+ 0x 03 FF FF FF FC
-------------------
  0x 04 12 34 56 74

当然,这会溢出,因为我们现在有一个 40 位的值,而指针是 32 位的,只能保存这么多信息。因此,我们一开始就输了04。这导致0x 12 34 56 74,即0x 12 34 56 78 - 4

于 2010-04-05T13:07:25.003 回答
3

是的,整数操作数被提升。但这并不重要。如果它是无符号类型,则uiVal不能。-1可能你做到了

unsigned int uiVal = -1;
pointer + uiVal ...

但这将与

pointer + UINT_MAX ...

如果指针可以保存的地址范围无法应对这种添加,这可能会导致未定义的行为。该标准在5.7/4

对于这些运算符,指向非数组对象的指针的行为与指向长度为 1 的数组的第一个元素的指针相同,该数组的元素类型为对象的类型。

当具有整数类型的表达式被添加到指针或从指针中减去时,结果具有指针操作数的类型。如果指针操作数指向数组对象的元素,并且数组足够大,[...]。如果指针操作数和结果都指向同一个数组对象的元素,或者超过数组对象的最后一个元素,则计算不应产生溢出;否则,行为未定义。

也就是说,如果结果指针不在同一个数组中或不在最后一个数组中,或者如果它存在但由于溢出而这样做,则行为未定义。

于 2010-04-05T13:04:19.737 回答
0

我认为正确的操作数被转换为 ptrdiff_t 类型,这似乎是签名的。

于 2010-04-05T13:04:45.040 回答