Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory Layout during downcasting in c++

Tags:

c++

class Parent {
public:
    void sleep() {cout<<"Paren::sleep";}
};

class Child: public Parent {
public:
    void gotoSchool(){cout<<"chil::gotoSchool";}
};


int main( ) 
{
  Parent parent;
  Child child;

  // upcast - implicit type cast allowed
  Parent *pParent = &child;  //OK.

  // downcast - explicit type case required 
  Child *pChild =  (Child *) &parent; //OK due to typecast but not safe when we call child specific method

  pParent -> sleep();
  pChild -> gotoSchool(); //Undefined but works ok on VS08

  return 0; 
}

Question:

In the above code pChild -> gotoSchool(); is undefined as per standard. By the word undefined , it means it may or may not work. It worked for me. But my question is why did it work? It shouldn't have. I cannot visualize the layout object in memory.

//Parent object doesn't even know anything about gotoSchool method, so how come a pointer to Parent object still prints gotoSchool. The question here is not about the undefined behavior, its more about how can it even know about the gotoSchool method, so even by sheer luck it shouldnt call the gotoSchool method to print Child::gotoSchool.

Parent         Child
-----------     -------------
|         |     |           |
|  sleep  |     |   sleep   |
|         |     | gotoSchool| 
-----------     ------------- 

Ofcourse the object doesnt contain inside it the member functions but only data members. The above diagram is just for explanation.

like image 496
anurag86 Avatar asked Feb 18 '26 19:02

anurag86


1 Answers

But my question is why did it work?

Because the way your compiler was implemented happens to lead to that behaviour.

It shouldn't have.

If you mean that a compiler shouldn't allow that behaviour, well... standard doesn't require that.

It may, it can, and it did.

How it works

I don't have the source code of visual studio at hand so I can't tell you exactly how it works. But generally speaking, member functions are implemented as regular functions, except with an extra parameter which contains the address of the object. The location of the function itself in the memory is not associated with the memory of the objects. The compiler knows exactly where the code for the function is.

You might even be able to do ((Child*)nullptr)->gotoSchool(); and observe the same (undefined) behaviour.

There is no obvious reason why it couldn't have the observed behaviour.

I cannot visualize the layout object in memory

The memory layout of the object is irrelevant to the function because the function never uses any of the object's memory.

like image 171
eerorika Avatar answered Feb 21 '26 08:02

eerorika



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!