The behaviour of the cast comes down to [expr.static.cast]/13;
A prvalue of type “pointer to cv1
void
” can be converted to a prvalue of type “pointer to cv2T
”, whereT
is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If the original
pointer value represents the addressA
of a byte in memory andA
does not satisfy the alignment requirement ofT
, then the resulting pointer value is unspecified. Otherwise, if the original pointer value points to an objecta
, and there is an objectb
of typeT
(ignoring cv-qualification) that is pointer-interconvertible witha
, the result is a pointer tob
. Otherwise, the pointer value is unchanged by the conversion.
The definition of pointer-interconvertible is:
Two objects a and b are pointer-interconvertible if:
- they are the same object, or
- one is a union object and the other is a non-static data member of that object, or
- one is a standard-layout class object and the other is the first non-static data member of that object, or, if the object has no non-static data members, the first base class subobject of that object, or
- there exists an object c such that a and c are pointer-interconvertible, and c and b are pointer-interconvertible.
So in the original code, s
and s.x
are pointer-interconvertible and it follows that (int &)s
actually designates s.x
.
So, in the strict aliasing rule, the object whose stored value is being accessed is s.x
and not s
and so there is no problem, the code is correct.