C++ Memory layout of inheritance
Asked Answered
R

5

4

If I have two classes, one inheriting from the other, and the child class only containing functions, will the memory layout be the same for both classes?

e.g.

class Base {
  int a,b,c;
};

class Derived: public Base {
  // only functions.
};

I've read that the compiler can not reorder data members, and I do not require multiple-inheritance on the Derived class. Is there any situation where the memory layout will not be the same? (Multiple inheritance may be needed for the Base class)

Recital answered 9/7, 2012 at 22:36 Comment(0)
H
3

Both Base and Derived here are standard layout classes. Since standard layout is intended to for interoperation with other languages (most notably C), yes, you can expect the layout to be the same for both. If you add multiple-inheritance to the mix however, the result may or may not be a standard layout class. You can check the rules for that in the post linked above.

Homosexuality answered 9/7, 2012 at 22:40 Comment(0)
P
1

The layout must be the same, because you can access derived instances through pointers to the base class.

Which means they would still be the same even if you had added data members.

Which also means it would've been the same even if you had used multiple inheritance.
(Although in that case, you might need to specifically do static_casts to specify which instance of the base you're referring to, since the derived class pointer need not be the same as the base class pointer.)

Principalities answered 9/7, 2012 at 22:40 Comment(4)
That requirement is not enough. It can still be fulfilled without forcing the same layout. Consider |a|b|c| for the layout of Base, and |junk|a|b|c| for the layout of Derived. When you static_cast from Derived to Base, the compiler would adjust the pointer to be right after the junk (that's what happens with MI, for example). There are other requirements that forbid padding at the start, though, so your conclusion is correct, even if from the wrong premises.Homosexuality
@R.MartinhoFernandes: Uh, that's exactly what I said when I wrote the derived class pointer need not be the same as the base class pointer. The pointers aren't the same, but once they're pointing to the same type, the layout for that type must be the same, because eventually the code will have no idea where the pointer came from -- even if the object is an instance of a derived class, even with MI.Principalities
Then we must have be using different definitions of layout. In my view, if the pointer to the derived class does not point to the same address as the pointer to the base class, the layout cannot be the same. The code doesn't need to know where the pointer came from: if it's a Derived*, it points to junk and data starts sizeof(junk) ahead; if it's a Base* it points to a, regardless if that's in the middle of a Derived or not. The pointer type is all that is needed.Homosexuality
@R.MartinhoFernandes: Oh, that's not what I meant by layout. I assumed the upcasting was already performed.Principalities
M
1

It varies compiler to compiler, but I would think for the most common compilers your assumption would be correct. g++/gcc for certain work as you suggest, I'm not sure about other though.

Manas answered 9/7, 2012 at 22:40 Comment(0)
S
1

As they are, the layout of both classes is the same, but note that if you add any virtual function to the derived type, then the layout will change (or at least can change).

Now, from the description it seems that what you are trying to do is to create a type to provide member functions on top of an existing class, if that is the case, you should probably consider other different designs, like using free functions (C style).

Slapup answered 10/7, 2012 at 2:41 Comment(0)
M
0

DON'T count on it.

But the memory layout might in fact be the same for some common compilers.

Meakem answered 9/7, 2012 at 22:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.