Re: Neatest way to get the end pointer?
On Feb 6, 3:05 am, Keith Thompson <ks...@mib.org> wrote:
> vipps...@gmail.com writes:
> > On Feb 6, 2:08 am, Keith Thompson <ks...@mib.org> wrote:
> >> vipps...@gmail.com writes:
> >> > On Feb 6, 12:40 am, "Tomás Ó hÉilidhe" <t...@lavabit.com> wrote:
> >> >> I commonly use pointers to iterate thru an array. For example:
>
> >> >> int my_array[X];
> >> [snip]
> >> >> 1) my_array is an int[X]
> >> >> 2) &my_array is an int(*)[X]
> >> >> 3) &my_array+1 is the address of the non-existant array located after
> >> >> the current one.
> >> > And you invoke undefined behavior.
>
> >> [...]
>
> >> No, he doesn't. &my_array+1 is a valid address, just past the end of
> >> my_array. Computing this address is ok; attempting to dereference it
> >> would invoke UB.
> > I think that when the result of an expression is a non-valid pointer,
> > the behavior is undefined.
> > Correct me if I am wrong, but I have also seen comments in GNU code
> > like this:
> > --
> > /* ANSI C violation */
> > char * s = p - 1;
> > --
> > Where p points to the start of a string passed. 's' is never
> > dereferenced, only used for comparing purposes (while(p > s) or
> > something similar)
>
> Computing a pointer before the beginning of an array invokes UB;
> computing a pointer just past the end of an array does not.
>
> This is mentioned in passing in the answer to question 6.17 in the
> comp.lang.c FAQ, <http://www.c-faq.com/> (can anyone find a more
> explicit reference?).
>
> The standard's rather long-winded explanation of this is in C99
> 6.5.6p8 (quoting from n1256; there are no change bars on this
> paragraph):
>
> When an expression that has integer type is added to or subtracted
> from a pointer, the result has the type of the pointer operand. If
> the pointer operand points to an element of an array object, and
> the array is large enough, the result points to an element offset
> from the original element such that the difference of the
> subscripts of the resulting and original array elements equals the
> integer expression. In other words, if the expression P points to
> the i-th element of an array object, the expressions (P)+N
> (equivalently, N+(P)) and (P)-N (where N has the value n) point
> to, respectively, the i+n-th and in-th elements of the array
> object, provided they exist. Moreover, if the expression P points
> to the last element of an array object, the expression (P)+1
> points one past the last element of the array object, and if the
> expression Q points one past the last element of an array object,
> the expression (Q)-1 points to the last element of the array
> object. If both the pointer operand and the result point to
> elements of the same array object, or one past the last element of
> the array object, the evaluation shall not produce an overflow;
> otherwise, the behavior is undefined. If the result points one
> past the last element of the array object, it shall not be used as
> the operand of a unary * operator that is evaluated.
I have thought about this, and clearly the standard talks about
arrays.
If we have foo[N], then foo + N is a valid pointer that cannot be
dereferenced.
However, in foo = &bar; foo+1 is *not* a valid pointer because &bar is
a pointer, not an array.
Therefore, in OPs example, the expression cannot be computed and does
invoke undefined behavior.
Here is an example of what i am trying to say
--
int * foo;
int bar;
int baz[N];
foo = baz + N; /* valid */
foo = &bar + 1; /* invalid */
foo = &bar; /* valid */
foo++; /* invalid */
--
|