What you're doing may be legal, but that depends on the real definition of class T
, so we can't know for sure based on the code you've shown.
Starting with C++11 §3.9.2/3:
Pointers to incomplete types are allowed although there are restrictions on what can be done with them.
Those restrictions are listed in §3.2/4:
A class type T
must be complete if:
- an object of type
T
is defined, or
- a non-static class data member of type
T
is declared, or
T
is used as the object type or array element type in a new-expression, or
- an lvalue-to-rvalue conversion is applied to a glvalue referring to an object of type
T
, or
- an expression is converted (either implicitly or explicitly) to type
T
, or
- an expression that is not a null pointer constant, and has type other than
void*
, is converted to the type pointer to T
or reference to T
using an implicit conversion, a dynamic_cast
or a static_cast
, or
- a class member access operator is applied to an expression of type
T
, or
- the
typeid
operator or the sizeof
operator is applied to an operand of type T
, or
- a function with a return type or argument type of type
T
is defined or called, or
- a class with a base class of type
T
is defined, or
- an lvalue of type
T
is assigned to, or
- the type
T
is the subject of an alignof
expression, or
- an exception-declaration has type
T
, reference to T
, or pointer to T
.
The 6th bullet appears pertinent here, as we can see in §5.2.10/7 that a reinterpret_cast
between pointer types is defined in terms of static_cast
:
An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue v
of type “pointer to T1
” is converted to the type “pointer to cv T2
”, the result is static_cast<cv T2*>(static_cast<cv void*>(v))
if both T1
and T2
are standard-layout types and the alignment requirements of T2
are no stricter than those of T1
, or if either type is void
. 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. The result of any other such pointer conversion is unspecified.
But because reinterpret_cast
static_cast
s to void*
first, then to the real resulting pointer type, that 6th bullet doesn't apply.
So, so far you're still in legal territory, despite T
being an incomplete type. However, if it turns out that T
is not a standard-layout type or has stricter alignment requirements than int
, then the last sentence in §5.2.10/7 holds true and you're invoking UB.