3.10/10
If a program attempts to access the stored value of an object through
a glvalue of other than one of the following types the behavior is
undefined:
- the dynamic type of the object,
- a cv-qualified version of the dynamic type of the object,
- a type similar (as defined in 4.4) to the dynamic type of the object,
- a type that is the signed or unsigned type corresponding to the dynamic type of the object,
- a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,
- an aggregate or union type that includes one of the aforementioned types among its elements or nonstatic data members (including,
recursively, an element or non-static data member of a subaggregate or
contained union),
- a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
- a char or unsigned char type.
Readers should be aware that the paragraph cited by the OP is a religious issue, as the basis of a disputed behavior of the g++ compiler. Any answer sowing doubt on the accuracy or completeness of this paragraph (and it's neither) will generally get downvoted on SO.
Here's an example of UB according to the paragraph you're citing:
struct X { int i; };
auto main() -> int
{
X o{ 0 };
return reinterpret_cast<int&>( o );
}
Considering each possibility in C++11 §3.10/10 in order:
Is “the dynamic type of the object” o
an int
?
No, the dynamic type is an X
.
Is int
perhaps “a cv-qualified version” of the dynamic type X?
No, X
is not an int
, cv-qualified or not.
Is int
“a type similar (as defined in 4.4) to the dynamic type of the object”?
Again, no. 4.4 deals with multi-level cv-qualification.
Well, is int
“a type that is the signed or unsigned type corresponding to the dynamic type of the object”?
No, there are no signed or unsigned versions of a class type like X
.
So what about “a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object”?
No.
Well, is int
perhaps “an aggregate or union type that includes one of the aforementioned types among its elements or nonstatic data members (including, recursively, an element or non-static data member of a subaggregate or contained union)”?
No, not that either.
So maybe int
is “a type that is a (possibly cv-qualified) base class type of the dynamic type of the object”?
No, an int
can’t be a base class.
Finally, is int
“a char
or unsigned char
type”?
No.
And this exhausts all possibilities, proving that according to that paragraph in isolation, this code has Undefined Behavior.
However, this code is guaranteed to work by another part of the standard (I guess mainly for C compatibility).
So, the paragraph you cite isn't 100% good even for the completely platform-independent formal.
Edit: "dyp" asked in a comment how this relates to use of an xvalue. An xvalue is a glvalue, so one can just substitute an xvalue for the lvalue expression o
. An example of such xvalue is an rvalue reference returned from a function, e.g. from std::move
:
#include <utility>
using std::move;
struct X { int i; };
template< class T >
auto ref( T&& r ) -> T& { return r; }
auto main() -> int
{
X o{ 0 };
return reinterpret_cast<int&>( ref( move( o ) ) );
}
All this does is however to mask the essentials.