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

R

raphael.maggi

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?
 
B

Ben Bacarisse

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.
 
S

Spiros Bousbouras

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;
 
B

Ben Bacarisse

Pietro Cerutti said:
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.)
 
R

Raphael Maggi

Pietro Cerutti said:
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?
 
J

jameskuyper

Pietro said:
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.
Try instead with this:

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.
 
R

Raphael Maggi

Pietro said:
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
 
B

Ben Bacarisse

Raphael Maggi said:
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. [...]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top