Jump to content
  • Advertisement
Sign in to follow this  
MGB

C++ casting question

This topic is 3673 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there, I have a horrible crash in my program that seems to have been down to this cast here:
IObjectTargetter* objTarg = reinterpret_cast<IObjectTargetter*>(mTargetters);
objTarg->DoSomething();  // Crash!


Now, if I do two stages of cast like this, everything works fine in the same circumstances:
CDefenseStructure* ds = reinterpret_cast<CDefenseStructure*>(mTargetters);
IObjectTargetter* objTarg = reinterpret_cast<IObjectTargetter*>(ds);
objTarg->DoSomething();  // OK this time...


Here's my relevant class hierarchy:
class CBaseObject {};
class CDefenseStructure : public CBaseObject, public IObjectTargetter {};
std::vector<CBaseObject*> mTargetters;


(The object in mTargetters is definitely valid and is a-kind-of IObjectTargetter.) The pointer in both cases is exactly the same value. In the first case, the ptr was shown in the debugger as containing all sorts of rubbish. So it seems the compiler was having trouble getting the correct type in the first case..? Anyone with more C++ knowledge than me explain why I need the two casts instead of just one?

Share this post


Link to post
Share on other sites
Advertisement
Repeat after me: I will never use reinterpret_cast for class pointers. Class pointers have some compiler-enforced offset magic added to them which is simply ignored by reinterpret_cast, because reinterpret_cast usually changes the type without changing the value. Only static_cast and dynamic_cast can reliably perform the subtle manipulations required for this to work.

In this situation, there's no clean compile-time cast from BaseObject to unrelated class IObjectTargetter, because there are no clean compile-time casts between unrelated objects. A dynamic_cast would get this right, because it can explore the inheritance tree at runtime and notice that the object really inherits from IObjectTargetter, and get a pointer ot it.

Otherwise, you need to use an intermediary related type, which happens to be a CDefenseStructure.

Of course, the obvious question here is, why doesn't a list of targetters store pointers to "base objects" instead of pointers to, well, targetters ?

Share this post


Link to post
Share on other sites
I will try to never use reinterpret_cast for class pointers... ;)

Magic eh? Doh. What did people do before the cast templates? *Have* to use the multi-stage cast I presume.

Yeah I started out with a list of targetters, but changed it while isolating this problem :)

Cheers ToohrVyk!

Share this post


Link to post
Share on other sites
Quote:
Original post by Aph3x
I will try to never use reinterpret_cast for class pointers... ;)

Magic eh? Doh. What did people do before the cast templates? *Have* to use the multi-stage cast I presume.

Yeah I started out with a list of targetters, but changed it while isolating this problem :)

Cheers ToohrVyk!

If the C++ cast operators didn't exist, then it wouldn't have been C++. Plain old C didn't have class hierarchies, so plain old C-style casts were fine. reinterpret_cast is basically just a C-style cast, which, as you've discovered, interacts badly.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!