Pointer arithmetic and comparisons.
Chris Torek
chris at mimsy.umd.edu
Wed Dec 13 17:06:48 AEST 1989
In article <232 at bohra.cpg.oz> ejp at bohra.cpg.oz (Esmond Pitt) writes:
>... you should test for <= &buffer[last-1], not < &buffer[last].
It makes no difference:
> char *p = buffer;
> char *e = &buffer[len-1];
>
> while ((*p++ = getchar()) != EOF && p <= e) {
(For the moment, let us ignore the fact that *p==EOF might well never be
true.) Chances are that if the loop
for (p = base; p <= &base[SIZE - 1]; p++)
works, the loop
for (p = base; p < &base[SIZE]; p++)
will also work. In particular, the latter loop tends to fail when
base+SIZE `wraps around', as it were, to 0. That is, &base[SIZE] is
very small, and hence (p < &base[SIZE]) is always false.
Suppose this is the case. Now let p be &buf[SIZE - 1], and assume we
are working on the former loop (p <= &base[SIZE - 1]). Then, if
arithmetic works `as expected', p++ will cause p to wrap around to zero,
and the next iteration will test a very small `p' against a large address
and the loop will continue. That is, the loop will run forever, rather
than not at all.
The only time something useful happens is when &base[SIZE] is computed
in a different way than (&base[SIZE - 1]) + 1. Any system that does
this is not compiling C code correctly.
The situation is almost exactly the same as the case of
for i := 0 to maxint do ... od;
which must be coded in C as
for (i = 0;; i++) {
...
if (i == INT_MAX) break;
}
(or any equivalent). The variable i must not be incremented when
it is INT_MAX, as the result can either be overflow or INT_MIN (e.g.,
from 32767 to -32768, or from 2147483647 to -2147483648).
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris at cs.umd.edu Path: uunet!mimsy!chris
More information about the Comp.lang.c
mailing list