Jump to content

  • Log In with Google      Sign In   
  • Create Account


Static cast and unitialize variable?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 Juliean   GDNet+   -  Reputation: 2365

Like
0Likes
Like

Posted 01 April 2013 - 03:40 AM

Hello,

 

consider this code. Can somebody tell me why the first example doesn't work, but the second does?

 

    void ReceiveMessage(const BaseMessage& message)
    {
        if(message.m_family == BoundingVisualize::family())
        {
            m_bRender = !m_bRender;
        }
        else if(message.m_family == PickObject::family())
        {
            //works
            TranslatePickMessage(message);
        }
    }

    void TranslatePickMessage(BaseMessage message)
    {
        m_pSelected = static_cast<PickObject*>(&message)->pObject;
    }
	void ReceiveMessage(const BaseMessage& message)
	{
		if(message.m_family == BoundingVisualize::family())
		{
			m_bRender = !m_bRender;
		}
		else if(message.m_family == PickObject::family())
		{
                        //doesn't ... wtf?
			BaseMessage msg = message; // msg(message) doesn't work eigther
			m_pSelected = static_cast<PickObject*>(&msg)->pObject;
		}
	}

Since I can't cast the const reference, I need to first make a copy of the message struct. Now in the second example, I first get a warning about msg not being initialized in the cast line, while I clearly make a copy of the const message, then if the line is called, an exception for really using an unitialized variable is thrown. Why? In the first example it passes, though from what I understand, exactly the same thing should happen. msg does indeed get correctly assigned, and this works too:

            BaseMessage msg = message;
            BaseMessage* pMsg = &msg;
            m_pSelected = static_cast<PickObject*>(pMsg)->pObject;

Whats going on here?


Edited by The King2, 01 April 2013 - 03:40 AM.


Sponsor:

#2 Hodgman   Moderators   -  Reputation: 28613

Like
4Likes
Like

Posted 01 April 2013 - 04:03 AM

I need to first make a copy of the message struct

This causes all of your examples to be invalid. None of them should work.
When you take a polymorphic object, and copy it to just an instance of the base type, it's called "slicing". All of the actual derived type infomation is lost, and only the base part is copied:
http://en.wikipedia.org/wiki/Object_slicing
http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c

When you cast msg to a PickObject, this is an invalid cast. msg is a BaseMessage only; it is not a PickObject. So when you try to read the pObject member with static_cast<PickObject*>(&msg)->pObject, this member doesn't exist, and the memory access is erroneous. Often, such an illegal operation will seem to work without error, and you'll just be reading some random bit of RAM, other times you'll be lucky enough to get a crash/exception telling you that you've done something wrong.

It looks like what you want is:

void TranslatePickMessage(const BaseMessage& message)
{
  const PickObject& pickMessage = static_cast<const PickObject&>(message);
  m_pSelected = pickMessage.pObject;
}

Edited by Hodgman, 01 April 2013 - 04:06 AM.


#3 Juliean   GDNet+   -  Reputation: 2365

Like
0Likes
Like

Posted 01 April 2013 - 04:38 AM

Ah, you where right, it would have probably been more clear if I'd split that cast and pObject access in two seperate lines. Even with the cast theoretically working pObject would indeed have been sliced. Meanwhile I got it to work by using dynamic_cast and passing the message as non const reference, but that required me to put an unnecessary virtual dummy function to BaseMessage, plus it wasn't const correct anymore. Didn't think about I could simply cast to another const reference, thanks!






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS