4

I've done a search and I’ve found nothing relevant to my query. I am currently debugging a C optimizer and the code in question looks like this:

while( x-- )
array[x] = NULL;

What should happen in this instance? And should the result of this logic be consistent across all compilers?

Lets say that the initial value of x in this case is 5.

The problem is that the program crashes, my understanding is that it is caused by a negative array element reference.

Any help would be appreciated.

Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
Ahmad Badoura
  • 43
  • 1
  • 3
  • 3
    The array will never be indexed by a negative value (provided `x` starts of with a non-negative number). When `x` becomes `0` (followed by the decrement to `-1`), the body will not be executed anyway since a value of `0` is considered false. – Jeff Mercado Mar 21 '11 at 05:20
  • Since the end of the controlling expression of a while loop is a sequence point, I wouldn't expect it to make any difference whether you use post-increment or pre-increment in this case. Unless I'm missing something I wouldn't expect x to become negative. Is there more code that might shed a little more light on the subject? – Sean Mar 21 '11 at 05:27
  • @Sean: It will make a difference - preincrement will terminate the loop one iteration earlier. – caf Mar 21 '11 at 05:30
  • @Sean: I provided an example in my answer with *unsigned* index. The fact that the index is *unsigned* (if it is) is what makes the post-increment (specifically *post*) important. In any case, if you use pre-increment, the cycle will terminate before processing the `array[0]`. – AnT stands with Russia Mar 21 '11 at 05:32

3 Answers3

7

This cycle will end with x equal to -1 (assuming x is signed), but its body will not produce access to array[-1] at the last step. The last array access is to array[0]. The behavior is consistent across all implementations.

In other words, there's no problem with negative index array access in the code you quoted. But if you attempt to access array[x] immediately after the cycle, then you'll indeed access array[-1].

The code you quoted is a variation of a fairly well-known implementational pattern used when one needs to iterate backwards over an array using an unsigned variable as an index. For example

unsigned x;
int a[5];

for (x = 5; x-- > 0; )
  a[x] = 0;

Sometimes less-experienced programmers have trouble using unsigned indices when iterating backwards over an array. (Since unsigned variables never have negative values, a naive implementation of the cycle termination condition as x >= 0 does not work.) This approach - i.e. post-increment in the cycle termination condition - is what works in such cases. (Of course, it works with signed indices as well).

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • 1
    Still I find `for (unsigned x = 5; x <= 5; x--)` much easier to read. – Jens Gustedt Mar 21 '11 at 07:20
  • 1
    @Jens Gustedt: Firstly, in that case it should be `for (unsigned x = 4; x <= 4; ...`. Secondly, the logic behind your condition is not immediately apparent (yes, I know how it works, but nevertheless...). I'd probably prefer `for (unsigned x = 4; x != -1; x--)` instead, although for an unprepared reader the comparison of an *unsigned* variable with `-1` might look confusing as well. The beauty of the last variant is that it also works with signed types. – AnT stands with Russia Mar 21 '11 at 07:39
  • right for the `4` instead of `5`. So you see that the original version is really confusing for some people :) `x != -1` is ok for me, still I think that `x <= 4` is a perfect expression that captures exactly the range of the `unsigned` values. – Jens Gustedt Mar 21 '11 at 07:55
2

If the initial value of x is 5, it will execute:

array[4] = NULL;
array[3] = NULL;
array[2] = NULL;
array[1] = NULL;
array[0] = NULL;

If x is a signed type, then the final value of x will be -1; otherwise, it will be the maximum value of the type.

caf
  • 233,326
  • 40
  • 323
  • 462
0

Make sure x is non negative before processing the while loop(precondition). Also x value will be -1 when the process leaves the while loop(post condition). Therefore, after leaving while loop, you should not access the array using x as index.

Prince John Wesley
  • 62,492
  • 12
  • 87
  • 94