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

纵然是瞬间 提交于 2019-11-27 06:53:07

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.
sharptooth

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.

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'; }

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".

As far as I can tell your choice 1 (two chained static_cast) is dreaded undefined behaviour. Static cast only guarantees that casting pointer to void * and then back to original pointer works in a way that the resulting pointer from these to conversions still points to the original object. All other conversions are UB. For pointers to objects (instances of the user defined classes) static_cast may alter the pointer value.

For the reinterpret_cast - it only alters the type of the pointer and as far as I know - it never touches the pointer value.

So technically speaking the two choices are not equivalent.

EDIT: For the reference, static_cast is described in section 5.2.9 of current C++0x draft (sorry, don't have C++03 standard, the draft I consider current is n3225.pdf). It describes all allowed conversions, and I guess anything not specifically listed = UB. So it can blow you PC if it chooses to do so.

Using of C Style casting is not safer. It never checks for different types can be mixed together. C++ casts helps you to make sure the type casts are done as per related objects (based on the cast you use). This is the more recommended way to use casts than using the traditional C Style casts that's always harmful.

Look, people, you don't really need reinterpret_cast, static_cast, or even the other two C++ styles casts (dynamic* and const).

Using a C style cast is both shorter and allows you to do everything the four C++-style cast let you do.

anyType someVar = (anyOtherType)otherVar;

So why use the C++-style casts? Readability. Secondly: because the more restrictive casts allow more code safety.

*okay, you might need dynamic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!