From Take the address of a one-past-the-end array element via subscript: legal by the C++ Standard or not?
It seems that there is language specific to taking the address of one more than an array end.
Why would 2 or 2,000,000 past the end be an issue if it's not derefferenced?
Looking at some simple loop:
int array[];
...
for (int i = 0: i < array_max; ++i)
{
int * x = &array[i *2]; // Is this legal
int y=0;
if (i * 2 < array_max) // We check here before dereference
{
y = *x; // Legal dereference
}
...
}
Why or at what point does this become undefined, in practice it just sets a ptr to some value, why would it be undefined if it's not refferenced?
More specifically - what example of anything but what is expected to happen could there be?
It does, however, allow a pointer to point at one element beyond the end of the array. The distinction is important. Thus, this is OK: char array[N]; char *p; char *end; for (p = array, end = array + N; p < end; ++p) do_something(p);
The address of an array is the address of the first element of the array. In the above array, the first element is allocated 4 bytes. The number of the first byte is the address of the element. Similarly, the second element is also residing on the next 4 bytes.
An array is a collection of elements of the same type placed in contiguous memory locations that can be individually referenced by using an index to a unique identifier. Five values of type int can be declared as an array without having to declare five different variables (each with its own identifier).
A typical declaration for an array in C++ is: type name [elements]; where type is a valid type (such as int , float ...), name is a valid identifier and the elements field (which is always enclosed in square brackets [] ), specifies the length of the array in terms of the number of elements. int foo [5];
The key issue with taking addresses beyond the end of an array are segmented architectures: you may overflow the representable range of the pointer. The existing rule already creates some level of pain as it means that the last object can't be right on the boundary of a segment. however, the ability to form this address was well established.
Since array[i *2]
is equivalent to *((array) + (i*2))
, we should look at the rules for pointer addition. C++11 §5.7 says:
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.
So you have undefined behaviour even if you don't perform indirection on the pointer (not to mention that you do perform indirection, due to the expression equivalence I gave at the beginning).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With