# Calculating the address of the element past the end of the array

Discussion in 'C Programming' started by raphael.maggi@gmail.com, May 11, 2009.

1. ### Guest

Is this a valid way of calculating the address of the element past the
end of an array?

int main() {
int array[10];
int *ptr = &array[10];

return 0;
}

is it acessing the element or just calculating its address, or both?

, May 11, 2009

2. ### Ben BacarisseGuest

writes:

> Is this a valid way of calculating the address of the element past the
> end of an array?
>
> int main() {
> int array[10];
> int *ptr = &array[10];
>
> return 0;
> }

Yes.

> is it acessing the element or just calculating its address, or both?

All it does is calculate the address.

--
Ben.

Ben Bacarisse, May 11, 2009

3. ### Spiros BousbourasGuest

On 11 May, 17:31, wrote:
> Is this a valid way of calculating the address of the element past the
> end of an array?
>
> int main() {
> int array[10];
> int *ptr = &array[10];
>
> return 0;
>
> }
>
> is it acessing the element or just calculating its address, or both?

There is no element to access because you are passed the end of
the array. Even if you had initialised the array there would
still not be an element to access. So it only calculates the
address. You can achieve the same thing more simply by writing
ptr = array + 10;

--

Spiros Bousbouras, May 11, 2009
4. ### Ben BacarisseGuest

Pietro Cerutti <> writes:

> On Mon, 11 May 2009 09:31:15 -0700, raphael.maggi wrote:
>
>> Is this a valid way of calculating the address of the element past the
>> end of an array?
>>
>> int main() {
>> int array[10];
>> int *ptr = &array[10];
>>
>> return 0;
>> }
>>
>> is it acessing the element or just calculating its address, or both?

>
> It is both accessing the element and then getting the address of it.

<panto audience>
Oh, no it isn't!
</panto audience>

Short-hand reasoning is: array[0] is *(array + 10) so the RHS is
&*(array + 10). & and * cancel out in such an expression. The result
is that no access is implied or done.

(The wording in the standard explicitly covers the [] case but I think
it is simpler to remember the general rule.)

--
Ben.

Ben Bacarisse, May 11, 2009
5. ### Raphael MaggiGuest

On May 11, 2:16 pm, Ben Bacarisse <> wrote:
> Pietro Cerutti <> writes:
> > On Mon, 11 May 2009 09:31:15 -0700, raphael.maggi wrote:

>
> >> Is this a valid way of calculating the address of the element past the
> >> end of an array?

>
> >> int main() {
> >>     int array[10];
> >>     int *ptr = &array[10];

>
> >>     return 0;
> >> }

>
> >> is it acessing the element or just calculating its address, or both?

>
> > It is both accessing the element and then getting the address of it.

>
> <panto audience>
> Oh, no it isn't!
> </panto audience>
>
> Short-hand reasoning is: array[0] is *(array + 10) so the RHS is
> &*(array + 10).  & and * cancel out in such an expression.  The result
> is that no access is implied or done.

why they cancel out?
shouldn't the dereference occurs first and then the reference?

Raphael Maggi, May 11, 2009
6. ### jameskuyperGuest

Pietro Cerutti wrote:
> On Mon, 11 May 2009 09:31:15 -0700, raphael.maggi wrote:
>
> > Is this a valid way of calculating the address of the element past the
> > end of an array?
> >
> > int main() {
> > int array[10];
> > int *ptr = &array[10];
> >
> > return 0;
> > }
> >
> > is it acessing the element or just calculating its address, or both?

>
> It is both accessing the element and then getting the address of it.

6.5.3.2p3: "if the operand is the result of a [] operator, neither the
& operator nor the unary * that is implied by the [] is evaluated and
the result is as if the & operator were removed and the [] operator
were changed to a + operator."

In other words: &array[10], &*(array+10), and array+10 all mean
exactly the same thing. None of them actually accesses the (non-
existent) element.

>
> size_t address = (size_t) &array + sizeof(array) * sizeof(*array)

* I think you're assuming that sizeof(array) gives the number of
elements in the array, and that sizeof(*array) gives the number of
bytes in each element, so that multiplying them will give you the
total size of the array in bytes. That's incorrect: sizeof(array)
gives you the size of the array in bytes; no multiplication is
required.

* You're assuming that size_t is big enough to hold an address; that's
not guaranteed - that's what intptr_t and uintptr_t are for. I'll
assume that you meant to replace size_t with intptr_t.

* You're assuming that the result of converting a pointer to intptr_t
is the address. The result of such a conversion is implementation-
defined. A footnote says "The mapping functions for converting a
pointer to an integer or an integer to a pointer are intended to be
consistent with the addressing structure of the execution
environment.", however, footnotes are not normative, and even if it
were, "consistent with the addressing structure" doesn't have to mean
that it's the actual address. In particular, it's not necessarily the
case that adding the sizeof of the array to that address will be
meaningful. The number could, for instance, have a segment number in
the low-order bytes, and an offset within the segment in the high-
order bytes, in which case such an addition would produce a thoroughly
meaningless result.

jameskuyper, May 11, 2009
7. ### Raphael MaggiGuest

On May 11, 2:46 pm, jameskuyper <> wrote:
> Pietro Cerutti wrote:
> > On Mon, 11 May 2009 09:31:15 -0700, raphael.maggi wrote:

>
> > > Is this a valid way of calculating the address of the element past the
> > > end of an array?

>
> > > int main() {
> > >     int array[10];
> > >     int *ptr = &array[10];

>
> > >     return 0;
> > > }

>
> > > is it acessing the element or just calculating its address, or both?

>
> > It is both accessing the element and then getting the address of it.

>
> 6.5.3.2p3: "if the operand is the result of a [] operator, neither the
> & operator nor the unary * that is implied by the [] is evaluated and
> the result is as if the & operator were removed and the [] operator
> were changed to a + operator."
>
> In other words: &array[10], &*(array+10), and array+10 all mean
> exactly the same thing. None of them actually accesses the (non-
> existent) element.

I think this clarified my question

thank you all

Raphael Maggi, May 11, 2009
8. ### Ben BacarisseGuest

Raphael Maggi <> writes:

> On May 11, 2:16Â pm, Ben Bacarisse <> wrote:
>> Pietro Cerutti <> writes:
>> > On Mon, 11 May 2009 09:31:15 -0700, raphael.maggi wrote:

>>
>> >> Is this a valid way of calculating the address of the element past the
>> >> end of an array?

>>
>> >> int main() {
>> >> Â  Â  int array[10];
>> >> Â  Â  int *ptr = &array[10];

>>
>> >> Â  Â  return 0;
>> >> }

>>
>> >> is it acessing the element or just calculating its address, or both?

>>
>> > It is both accessing the element and then getting the address of it.

>>
>> <panto audience>
>> Oh, no it isn't!
>> </panto audience>
>>
>> Short-hand reasoning is: array[0] is *(array + 10) so the RHS is
>> &*(array + 10). Â & and * cancel out in such an expression. Â The result
>> is that no access is implied or done.

>
> why they cancel out?
> shouldn't the dereference occurs first and then the reference?

They cancel out because the language standard says they do. See
6.5.3.2 paragraph 3:

3 [...] If the operand is the result of a unary * operator, neither
that operator nor the & operator is evaluated and the result is as
if both were omitted, except that the constraints on the operators
still apply and the result is not an lvalue. Similarly, if the
operand is the result of a [] operator, neither the & operator nor
the unary * that is implied by the [] is evaluated and the result
is as if the & operator were removed and the [] operator were
changed to a + operator. [...]

--
Ben.

Ben Bacarisse, May 11, 2009