0

I saw this question. this post is so old. so i got different output.

test code

#include <iostream>

class M{
        char k[ 3 ];
        public:
            void m(){};
        };

class A{
        char k[ 3 ];
        public:
        virtual void a(){};
        };

class B : public  A{
        char j[ 3 ];
        public:
        virtual  void b(){};
        };

class C : public virtual A{
        char i[ 3 ];
        public:
        virtual void c(){};
        };

class D : public B, public C{
        char h[ 3 ];
        public:
        virtual void d(){};
        };

int main(){

    A a;
    B b;
    C c;
    D d;

    std::cout << sizeof(M) << std::endl;
    std::cout << sizeof(a) << std::endl;
    std::cout << sizeof(b) << std::endl;
    std::cout << sizeof(c) << std::endl;
    std::cout << sizeof(d) << std::endl;
}

and output

3
16
16
32
48

I understand why B have same size as A with this post. But still i dont get it why C's size is 32.

C has subobject of A(16) + new array(3) + pointer to A(8) and maybe padding(5).

It makes sense if B didn't reuse the padding, but it doesn't make sense because I thought B was the same size as A because he reused it.

I don't understand that result. can you help me to get it?!

I search some other post..

  • 3
    is it just me, but i don't understand why people are particularly interested in the actual sizes of objects? the size is whatever sizeof says it is - the actual value is not really interesting. – Neil Butterworth Jan 18 '23 at 03:46
  • Your code should not depend on actual memory sizes (or memory layout) of objects in any way (with some exceptional cases like serialization of data, not objects). What you see may be like this on one compiler and different on another. So trying to understand this is not all that useful. Unless you want to be a compiler builder yourself. – Pepijn Kramer Jan 18 '23 at 04:02
  • 2
    *"i dont get it why C's size is 32"* -- and yet you do: *"C has subobject of A(16) + new array(3) + pointer to A(8) and maybe padding(5)"*, where 16 + 3 + 8 + 5 is 32. – JaMiT Jan 18 '23 at 04:08
  • Hmm... *"It makes sense if B didn't reuse the padding, but it doesn't make sense because I thought B was the same size as A because he reused it."* -- Making sense of this sentence is challenging, but it occurred to me that perhaps you are trying to ask *"Why is it that `B` re-uses the padding in `A`, but `C` does not?"* Is that what you're trying to ask? And you don't like the answer "because that is what the compiler chose to do, given that the language does not mandate re-using padding"? (There is another reason, but at the moment I find the question too unclear to answer.) – JaMiT Jan 18 '23 at 04:25
  • 2
    The C++ standard does not impose any requirements on how memory for an instance of a derived class is organised. Obviously, a compiler (or the people implementing the compiler) need to make some decisions about that, otherwise compiled programs cannot use class types sensibly. But the decisions made by one compiler can be - and in practice, often are - different from decisions made by other compilers. In some cases, compiler *settings* can affect things (e.g. optimisation settings, settings that affect padding) as well. – Peter Jan 18 '23 at 04:53
  • 1
    The C++ standard does not mandate any particular layout for virtual base classes, but your compiler just appears to be using a particularly memory-inefficient one. There's no reason to store a pointer to the base object in the object; it is much more efficient to store an offset in the vtable – Chris Dodd Jan 18 '23 at 05:43
  • The representation is implementation defined, so any observations only applies to the given system/compiler. If you really want to look into the object representation, one approach is to create a few objects with easy-to-recognize member values and dump their byte representation to try to dissect the different parts. – nielsen Jan 18 '23 at 08:43

0 Answers0