That is actually not true. It cannot do casts of pointer to classes with multiple inheritance in some cases. The C-style cast will just reinterpret the pointer value, but a proper C++ style cast may actually change the value to handle multiple inheritance correctly.

What used to happen before the new C++ casts? They're templated and were templates introduced at the same time as multiple inheritance? (EDIT: presumably virtual inheritance was a problem? EDIT2: Hmm I guess all MI would be a problem with a C-style cast presumably you had to add on the sizeof the first base to cast to the 2nd via a cast to char*)

Edited by Paradigm Shifter, 01 May 2013 - 12:39 PM.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

reinterpret_cast<> is just slightly less evil than const_cast<> IMO. It generally should only be used in dire circumstances and/or where there is a need to interact with poorly specified code and/or code from languages other than C++.

One concrete example is moving from void* to any other pointer type. If you use void* to represent "any pointer type possible", the correct way to recover a real pointer is with reinterpret_cast<>. This can be useful when a C-style API (such as the Windows API) requires a void* as an opaque parameter but you know the actual type that should be passed through; examples include any callback system with a custom parameter in the Windows API.

What used to happen before the new C++ casts? They're templated and were templates introduced at the same time as multiple inheritance? (EDIT: presumably virtual inheritance was a problem? EDIT2: Hmm I guess all MI would be a problem with a C-style cast presumably you had to add on the sizeof the first base to cast to the 2nd via a cast to char*)

I have to correct me a bit, but I'm still a bit uncertain about the exact details so keep that in mind.

It seems to be that is not that C-style cast cannot cast with multiple inheritance which I implied, but that the behavior of the C-style cast can silently change. The correct way to cast between base classes in multiple inheritance, as I understand it, is via static_cast and derived classes. The C-style cast will do the right thing if if the full definition of the inheritance hierarchy is present. If not, the C-style cast will go ahead and do an incorrect reinterpret_cast, while the correct static_cast will fail.

The C-style cast will therefore cast correctly when the cast is doable, but will silently work and do the wrong thing when the cast cannot be done correctly.

reinterpret_cast<> is just slightly less evil than const_cast<> IMO. It generally should only be used in dire circumstances and/or where there is a need to interact with poorly specified code and/or code from languages other than C++.

One concrete example is moving from void* to any other pointer type. If you use void* to represent "any pointer type possible", the correct way to recover a real pointer is with reinterpret_cast<>. This can be useful when a C-style API (such as the Windows API) requires a void* as an opaque parameter but you know the actual type that should be passed through; examples include any callback system with a custom parameter in the Windows API.

Apparently there is some religious debate over whether to use static_cast<> or reinterpret_cast<> for that case. I suggest reading up on the controversy yourself and drawing your own conclusion; I personally prefer reinterpret_cast<> but my reasons are entirely subjective and may not be worth emulating :-)

If static_cast works I would use that since as you say it is less evil... reinterpret_cast should be for the case I mentioned earlier (i.e. don't change the address, just cast it to another type, AKA "compiler, I know what I am doing, trust me" cast).

EDIT: Multiple inheritance may mess that up though, I suppose. I can't be arsed reading a religious debate about it anyway ;)

Edited by Paradigm Shifter, 01 May 2013 - 01:20 PM.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

C-style cast: impossible_to_grep_for_cast. Java and C# really missed the boat on this one by not making it easier to do a search for casts. Visual Studio still hasn't got a "find any cast" search facility, which would be rather handy.

Edited by Paradigm Shifter, 01 May 2013 - 01:31 PM.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Reinterpret cast doesn't do anything ;) It just says to the compiler "here's this address, treat it as a pointer to this even though that would be illegal, I know what I'm doing".

static_cast can do lots of things like point to a different base object in the case of multiple inheritance or casting from a float to an int (completely changes the value, i.e. the very antithesis of "static").

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

If you want a really quick and basic summary, you can think of it like this:

reinterpret_cast is use to change the type but it won't change the underlying bits. For example, change the type of one pointer to another, or to put the value of a pointer in an integer.

static_cast is used to change the type and the logical value. For example, if you static_cast from a float to an integer, then the logical value is preserved; that is, if you cast from 1.0f, then the integer value is 1, even though the bits are completely different.

You can explicitly convert a pointer of a type A to a pointer of a type B if A is a base class of B. If A is not a base class of B, a compiler error will result.

You may cast an lvalue of a type A to a type B& if the following are true:

A is a base class of B

You are able to convert a pointer of type A to a pointer of type B

The type B has the same or greater const or volatile qualifiers than type A

A is not a virtual base class of B

The result is an lvalue of type B.

A pointer to member type can be explicitly converted into a different pointer to member type if both types are pointers to members of the same class. This form of explicit conversion may also take place if the pointer to member types are from separate classes, however one of the class types must be derived from the other.

First bullet point is obvious. 2nd involves whether you have defined conversion operators which are public in the class I believe (EDIT: or accessible in the context of the cast e.g. private conversion operators ok in the same class, etc.). 3rd one requires const_cast. Not sure about the virtual inheritance 4th case, I've never used virtual inheritance.

Edited by Paradigm Shifter, 01 May 2013 - 01:57 PM.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

You don't need a cast for that... although it does slice the object if you pass or copy by value (EDIT: And virtual functions won't work if you cast a Derived to a Base class). In C you would need a cast which is why well written C++ requires less casting shenanigans than C.

Edited by Paradigm Shifter, 01 May 2013 - 02:02 PM.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley