在for循环中使用关系运算符测试指针

Ash*_*wat 7 c arrays pointers

假设我有一个for循环,它使用如下指针在数组中存储零:

int *vp, values[5];

for(vp = &values[5-1]; vp >= &values[0]; vp--)
   *vp = 0;
Run Code Online (Sandbox Code Playgroud)

书中的指针表示这个循环存在问题,因为比较vp >= &values[0]未定义,因为它超出了数组的范围.但是怎么样?

Ric*_*III 2

假设一个指针相当于一个无符号整数,我们可以看到,只有从values地址 0 开始才会出现这个问题,在这种情况下,指针在递减后会回绕,变成UINT_MAX

为了直观地说明问题,让我们逐步了解所发生的情况,假设values从地址 0x0 开始:

iteration 1: 
vp = 0x4, *vp = 0;

iteration 2:
vp = 0x3, *vp = 0;

iteration 3: 
vp = 0x2, *vp = 0;

iteration 4:
vp = 0x1, *vp = 0;

iteration 5:
vp = 0x0, *vp = 0;

iteration 6:
vp = 0xFFFFFFFF; *vp = ?? // uh oh!
Run Code Online (Sandbox Code Playgroud)

因此,vp永远不会小于指针的最小值(即 0),并且会导致无限循环(假设所有内存都是可写的)或分段错误。

根据标准,这也是未定义的行为(因为您可以在数组之后寻址一个元素,但不能在数组之前寻址),但实际上,这在任何实际系统上都不会失败。

  • 此代码在使用段和偏移指针的实现上可能会失败,但它也可能会失败,因为优化器有权假设“vp >= &values[0]”永远不会在“vp”不指向该元素的情况下执行。数组或超出它的数组(因为这样做将是未定义的行为)。因此,优化器可能会认为该表达式始终为真,并且可能会消除它,从而导致无限循环。 (3认同)