Why do we have reinterpret_cast in C++ when two chained static_cast can do its job?

Solution 1:

There are things that reinterpret_cast can do that no sequence of static_casts 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:

  • A pointer to a POD-struct object, suitably converted using a 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.

Solution 2:

You need reinterpret_cast to get a pointer with a hardcoded address (like here):

int* pointer = reinterpret_cast<int*>( 0x1234 );

you might want to have such code to get to some memory-mapped device input-output port.

Solution 3:

A concrete example:

char a[4] = "Hi\n";
char* p = &a;

f(reinterpret_cast<char (&)[4]>(p));  // call f after restoring full type
      // ^-- any_cast<> can't do this...

// e.g. given...
template <typename T, int N>   // <=--- can match this function
void f(T (&)[N]) { std::cout << "array size " << N << '\n'; }

Solution 4:

Other than the practical reasons that others have given where there is a difference in what they can do it's a good thing to have because its doing a different job.

static_cast is saying please convert data of type X to Y. reinterpret_cast is saying please interpret the data in X as a Y.

It may well be that the underlying operations are the same, and that either would work in many cases. But there is a conceptual difference between saying please convert X into a Y, and saying "yes I know this data is declared as a X but please use it as if it was really a Y".