How to access object representation? To answer this question I divide it in 2 questions:
According to the
Working with const
pointers ensure that constness is not casted away:
5.2.10/2 The reinterpret_cast operator shall not cast away constness.
The pointer conversion is safe, because char
has not a stricter alignment requirement than some_type
, so that you may convert rep
back to a some_type*
:
5.2.10/7 An object pointer can be explicitly converted to an object pointer of a different type. (...) Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value.
Edit: In my understanding, there is no doubt about inter-convertibility between the pointer to an object and the pointer to its representation:
1.8/6: Unless an object is a bit-field or a base class subobject of zero size, the address of that object is the address of the first byte it occupies.
3.9/4: The object representation of an object of type T is the sequence of N unsigned char objects taken up by the object of type T, where N equals sizeof(T).
I understand that "taken up" is a synonym of "occupies". Note also that, the &
operator guarantees that:
5.3.1/3: (...) if the type of the expression is T, the result has type “pointer to T” and is a prvalue that is the address of the designated object
This is induced from the definition of the value representation, taken together with the memory model and the object lifecylcle.
However, your example is more complex:
rep[0]
may despite this property remain an undetermined value, if it is composed solely of padding bits. This is the case in your example, because the object has at least a size of 1, but as you have no member in it, the value representation is empty. rep[1]
can be undefined behavior, if sizeof(some_type)<2
because dereferencing a pointer passed the last element of an array is UB. Let's take a simple example:
class some_other_type {
int a;
std::string s;
};
There is an ambiguity when speaking about the memory occupied by an object:
int
, some size_t
for the string's length and some pointer to the chars in the string, like it would be done in C) ? The object representation corresponds to the first part. For objects that are not trivially copiable, the object representation is not self sufficient (i.e. in our example, the bytes stored in the string are not necessarily part of the object representation).
The value representation corresponds to the second part (and would include the bytes required to store the value of the string).
In plain words, this means that the address of an object is the address of its representation, but the object representation may contain padding and may not be sufficient to hold every data that belongs to the object.