Sign in to follow this  
muse1987

Difference between reinterpret_cast and two successive static_cast through void*

Recommended Posts

muse1987    184
Hi. This is just from my curiosity. I can cast a pointer value to pointer to unrelated type in two ways, by reinterpret_cast or by static_cast'ing to void* and then casting it again.

struct X;
struct Y;

Y* cast1( X* p )
{
    return reinterpret_cast<Y*>(p);
}

Y* cast2( X* p )
{
    return static_cast<Y*>(static_cast<void*>(p));
}



What's the difference between those two, if there's any? Could someone give me explanation? Thanks in advance

Share this post


Link to post
Share on other sites
ToohrVyk    1596
They are equivalent when they work (that is, on objects with compatible memory layouts). When they don't work, they will misbehave differently (reinterpret_cast usually leaves the numeric representation of the pointer as-is, whereas static_cast changes it).

Share this post


Link to post
Share on other sites
SiS-Shadowman    359
I think there is none, both casts are just unsafe as hell.
Imagine a class that's derrived from two other classes:

class foo{ public: int i; };
class bar{ public bool b; };
class foobar : public foo, public bar { short n; };




Casting from foobar to foo is no problem with both of your casts, but casting from foobar to bar or the otherway round is going to introduce terrible errors, because the base address is not modified, although it should.
If you don't need to, do not use reinterpret_cast or casts to void and back.

If you're interested in this topic, google for "mutliple inheritance and the this pointer". You should find the right topic in the first results. You will also read that casting to void and back with static_cast will not change the address in any way.

Share this post


Link to post
Share on other sites
muse1987    184
Thanks for your informations

@ ToohrVyk:
Quote:
reinterpret_cast usually leaves the numeric representation of the pointer as-is, whereas static_cast changes it

Does that mean static_cast may even change the numeric representation when casting to void* or back? :O

@ SiS-Shadowman:
I agree. I have been killed by void* several times :D Now the only case I use reinterpret_cast is when I declare typesafe handles.
BTW I usually play Byern Munich when I play FIFA

Yet I'd love to hear more opinions.
Thanks

Share this post


Link to post
Share on other sites
phresnel    953
Quote:
Original post by muse1987
Does that mean static_cast may even change the numeric representation when casting to void* or back? :O


It can be, yes. Imagine you have the following:

const float f = 0.123456f;
const int i = static_cast <int> (f); // i = 0
const float f_ = static_cast <float> (i); // f_ = 0.0f (approximately)


The same applies to all other types. Think of you have a 64bit pointer, that for some reason you have to convert to a 32bit address (maybe to interface with an old library), while it may work (as casting integers like int64_t to int32_t can work), it could end in an epic fail.

So, always when casting pointers, know what you are doing (though most of the time a cast to void* or char* and then back is safe).

Share this post


Link to post
Share on other sites
ToohrVyk    1596
Quote:
Original post by muse1987
Does that mean static_cast may even change the numeric representation when casting to void* or back? :O


Of course. It's explicitly allowed by the standard:
Quote:
C++ Standard, 4.10 §2
An rvalue of type ``pointer to cv T,'' where T is an object type, can be converted to an rvalue of type ``pointer to cv void.'' The result of converting a ``pointer to cv T'' to a ``pointer to cv void'' points to the start of the storage location where the object of type T resides, as if the object is a most derived object (intro.object) of type T (that is, not a base class subobject).


Enjoy.

Quote:
Yet I'd love to hear more opinions.
This is not a matter of opinion: by definition, the standard is right, and anyone who disagrees with the standard is wrong. If you'd rather find out yourself, you can find final draft versions of the C++ standard lying around on the web, and look up the definitions of the various casts.

Share this post


Link to post
Share on other sites
Bregma    9214
The main difference between casting through pointer-to-void and using interpret_cast<>() is that when you have a bug, grepping for "interpret_cast" will find it immediately whereas casting through pointer-to-void may require a little more effort.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this