-2

I'm reading through K&R C. In t he back there's some sample fopen code. I don't particularly understand one part.

#define OPEN_MAX 20

FILE _iob[OPEN_MAX] = {
    { 0, NULL, NULL, _READ, 0 },             // _READ = 01
    { 0, NULL, NULL, _WRITE, 1 },            // _WRITE = 02
    { 0, NULL, NULL, _WRITE | _UNBUF, 2 }    // _UNBUF = 04
};

FILE *fopen(char *name, char *mode)
{
    FILE *fp;

    for (fp = _iob; fp < _iob + OPEN_MAX; fp++)
    /* ... */
}

The statement fp < _iob + OPEN_MAX is what's tripping me up.

  • fp: file pointer
  • _iob: file array
  • OPEN_MAX: integer

It seems to be adding a file array to an integer, then evaluating whether or not it's larger than a file pointer! How is the statement fp < _iob + OPEN_MAX possible?

MD XF
  • 7,860
  • 7
  • 40
  • 71

2 Answers2

2
  1. The expression _iob + OPEN_MAX causes _iob to be treated as a pointer to its first element within this expression (this is called array-to-pointer decaying).
  2. The resulting FILE pointer is then offset by OPEN_MAX (the +).
  3. The < then compares the two resulting FILE pointers (pointers are just integers under the hood).
Community
  • 1
  • 1
Emil Laine
  • 41,598
  • 9
  • 101
  • 157
1

In most contexts, when you use an array as an l-value, it decays to a pointer to the first element of the array. So

fp < _iob + OPEN_MAX

is equivalent to:

fp < &(_iob[0]) + OPEN_MAX

And when you perform arithmetic on a pointer to an array element, it's equivalent to array indexing. So this is the same as:

fp < &(_iob[OPEN_MAX])
Barmar
  • 741,623
  • 53
  • 500
  • 612