Say I want to cast A*
to char*
and vice-versa, we have two choices (I mean, many of us think we've two choices, because both seems to work! Hence the confusion!):
struct A
{
int age;
char name[128];
};
A a;
char *buffer = static_cast<char*>(static_cast<void*>(&a)); //choice 1
char *buffer = reinterpret_cast<char*>(&a); //choice 2
Both work fine.
//convert back
A *pA = static_cast<A*>(static_cast<void*>(buffer)); //choice 1
A *pA = reinterpret_cast<A*>(buffer); //choice 2
Even this works fine!
So why do we have reinterpret_cast
in C++ when two chained static_cast
can do its job?
Some of you might think this topic is a duplicate of the previous topics such as listed at the bottom of this post, but it's not. Those topics discuss only theoretically, but none of them gives even a single example demonstrating why reintepret_cast
is really needed, and two static_cast
would surely fail. I agree, one static_cast would fail. But how about two?
If the syntax of two chained static_cast
looks cumbersome, then we can write a function template to make it more programmer-friendly:
template<class To, class From>
To any_cast(From v)
{
return static_cast<To>(static_cast<void*>(v));
}
And then we can use this, as:
char *buffer = any_cast<char*>(&a); //choice 1
char *buffer = reinterpret_cast<char*>(&a); //choice 2
//convert back
A *pA = any_cast<A*>(buffer); //choice 1
A *pA = reinterpret_cast<A*>(buffer); //choice 2
Also, see this situation where any_cast
can be useful: Proper casting for fstream read and write member functions.
So my question basically is,
reinterpret_cast
in C++?static_cast
would surely fail to do the same job?There are things that reinterpret_cast
can do that no sequence of static_cast
s can do (all from C++03 5.2.10):
A pointer can be explicitly converted to any integral type large enough to hold it.
A value of integral type or enumeration type can be explicitly converted to a pointer.
A pointer to a function can be explicitly converted to a pointer to a function of a different type.
An rvalue of type "pointer to member of X
of type T1
" can be explicitly converted to an rvalue of type "pointer to member of Y
of type T2
" if T1
and T2
are both function types or both object types.
Also, from C++03 9.2/17:
reinterpret_cast
, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa.