c++ difference between reinterpret cast and c style cast

末鹿安然 提交于 2019-12-03 09:48:55

reinterpret_cast and const_cast are ways of getting around the C++ type system. As you noted for reinterpret_cast, this usually translates to little or no assembly code.

static_cast mostly respects the C++ type system. It could convert a number from one type to another, or call a constructor, or call a conversion function. Or for a derived-to-base conversion, it might involve adding byte offsets and/or lookups into a vtable. static_cast can also bend the type system's rules by "downcasting" a pointer or reference from a non-virtual base type to a derived type, possibly subtracting a byte offset.

And then there are pointers-to-member. They're probably beside the point here, but static_cast does things to them more or less analogous to class pointer conversions.

dynamic_cast respects the C++ type system even more strictly. In its useful form, it checks at runtime whether or not a pointer/reference actually points/refers to an object of the specified type. It typically calls a magic library function under the covers.

A function-style cast with one argument has exactly the same effect as a C-style cast. (With more than one argument, a function-style call must be a class constructor call.) A C-style cast does the first thing that makes sense out of the following list:

  • a const_cast
  • a static_cast
  • a static_cast and then a const_cast
  • a reinterpret_cast, or
  • a reinterpret_cast and then a const_cast

One exception: C-style casts can ignore private and protected inheritance relations between classes, pretending they have a public inheritance relation instead.

C-style casts are usually not preferred in C++ because it's less specific about what you want to happen.

In what way do you mean "not dangerous"? reinterpret_cast is incredibly dangerous. It tells the compiler it is safe to ignore what it thinks it knows about the value.

It's not as dangerous as a c-style cast which throws away the const/volatileness of the value in question as well as any information about what it is pointing to.

Understanding these operations in assembly language is a bit pointless. They aren't assembly language constructs. They're C++ language constructs, that work something as follows:

static_cast - Effectively this converts an object from one type to another. Note this can change the value (static_cast<float>(1) doesn't have the same bit pattern as 1 for instance).

dynamic_cast - if this object can be considered to be another type through inheritance, then treat it as such, otherwise render it as zero. This won't change the value of a pointer but it does safely change the compilers view of it.

const_cast - throw away const (or volatile) qualifiers, which is not often a good idea as it allows you to destroy data the client thought was safe.

reinterpret_cast - treat the bit pattern as meaning something different to what the compiler thought it did. Usually used for pointers and hopefully rarely. reinterpret_casting an int into a float is unlikely to be a good idea, but it will keep the same bit pattern.

c-style-cast - Take the bit pattern, forget completely what you know about it, and treat it as something else. A dangerous and almost invisible combination of static_cast, reinterpret_cast and const_cast. It's not considered a good idea in C++ code because it's hard to spot in a review, and because it is not specific about what is happening.

In your example there are no differences between the C style cast and the reinterpret_cast, because you are casting between unrelated pointers, and there is no constness. If you have had a const on one part, reinterpret_cast would have choked when C style cast would have done the const_cast under the hood.

The danger of the reinterpret_cast (or of the C style cast) is precisely that it allows casting between unrelated objects. In your example, you have a high risk that when you dereference reCast (or reCast2) you get an error because you try to access a misaligned integer.

At low level, all casting have same effect (if they are valid) : they will all give the value or address. The main difference is :

  • a C style cast will (almost) always be allowed at compile time - I do not know examples where it will give a compile error but it might be compiler dependant
  • a reinterpret_cast will be allowed in same cases provided there is no constness change
  • a const_cast can only change constness
  • a static_cast will only be allowed (at compile time) between related types

All this cast were added in C++ to avoid the catch all mode of C style cast and allow for some compile and run time checks. - a dynamic_cast will only be allowed at compile time between related types and the compiler will insert code to control validity at run time

The difference is that with C-style cast in C++ file in some cases you will get error and cannot compile. reinterpret_cast solves such cases. Something like - you tell to compiler: "I know it is incompatible casting, but let assume it is ok". C++ is far more restricted than C for such things like casting.

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