[vox-tech] loop never exits!

Chanoch (Ken) Bloom kbloom at gmail.com
Thu Apr 22 07:03:23 PDT 2010


On Wed, 2010-04-21 at 19:20 -0700, Matthew Van Gundy wrote:
> On 4/21/10 3:26 PM, Jeff Newmiller wrote:
> >> There are many ways to skin a cat, here's one:
> >>
> >> void reverse(int forward[], int backward[], unsigned int n) {
> >>    unsigned i = n;
> >>    while(i-->  0) {
> >>      backward[n-i-1] = forward[i];
> >>    }
> >> }
> >
> > This reverses and then re-reverses it.
> 
> Nope, just reverses it once.  I'll admit, it isn't an idiomatic 
> construction, but it uses an unsigned index that counts down to reverse 
> an array since that's what Brian seemed to be after.

The most idiomatic construction in C for writing an iterator is to use
pointer arithmetic. i.e.

int* thearray;
size_t itssize;

for(int* iterator=thearray; iterator<thearray+itssize;++iterator){
  /* do something with the iterator */
}

The loop terminates when the address of iterator is one past the end of
the array. The C standard guarantees that you can *form* the address one
past the end of the array (i.e. on a 32-bit machine with 4GB of address
space, the last element of the array can't abut the end of RAM, or some
compiler-level hack is required to guarantee that you can form the
address). However, the C standard makes no guarantees about being able
to form the address *before* the array, so the following is not
guaranteed to work:

for(int* iterator=thearray+itssize-1; iterator>=thearray;--iterator){
  /* do something with the iterator */
}

The following idiom must be used instead:

int* iterator=thearray+itssize;
while( iterator-- > thearray){
  /* do something with the iterator. */
}

The asymmetry you're noticing with unsigned int indices is a similar
problem.



More information about the vox-tech mailing list