[c++] 자식 클래스는 부모 클래스의 padding을 복사하나요?

숭글·2023년 1월 19일
0

가상 상속을 받은 클래스의 size에 대해 공부하다가 의문이 든 부분..


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

... 생략

int main(){
... 

	std::cout << sizeof(A) << std::endl;
	std::cout << sizeof(B) << std::endl;
    
...

output >

16
16

B는 A를 상속받았는데 사이즈가 같다..! 🤷‍♀️ 왜!?

해답은 이 글에서 찾을 수 있었다.
[Stack Overflow] will the padding of base class be copied into the derived class?

#include <iostream>
using namespace std;

class A {
public:
	int valA;
	char a;
};

class B : public A {
public:
	char b;
};

class C : public B {
public:
	char c;
};
int main(){
	std::cout << sizeof(A) << " " << sizeof(B) << " " << sizeof(C) 
	<< std::endl;
	C c;
	printf("c 주소 : %p\nc.a의 주소 : %p\nc.b의 주소 : %p\nc.c의 주소 : %p\n",&c,&c.a,&c.b,&c.c);
}

output >

8 12 12
c 주소 : 0x7ffee2be9840
c.a의 주소 : 0x7ffee2be9844
c.b의 주소 : 0x7ffee2be9848
c.c의 주소 : 0x7ffee2be9849

A클래스의 사이즈는 8, B클래스의 사이즈는 12, C클래스의 사이즈는 12이다.

C는 B를 상속받는데 어떻게 사이즈가 같을 수 있지?


이유를 정리해보자면 이렇다.
<정답은 아니다!!!!!!!!!!!!!!>

  • B는 A의 padding을 재사용하지 못했고, C는 B의 padding을 재사용했다.

  • POD class의 padding은 재사용할 수 없다.

  • A는 POD class이고 B는 POD class가 아니다.
    👉 about POD

B is not a POD. so the padding of B can be reused for C::b.

The padding of A can't be reused for sub objects of B. because A is a POD class(= standard layout class, trivially copyable).


A:8 bytes = char:1 byte + int:4 bytes + pad: 3bytes
B:12 bytes = A:8bytes char:1 byte + pad: 3bytes
C:12 bytes = B:12 bytes - B's pad: 3bytes(reused) + char:1 byte


처음 코드를 다시 보면

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

A는 virtual 키워드를 사용하고 멤버 함수도 존재하므로 POD class라고 할 수 없다. (= trivially copyable)

A:16 bytes = char:3 bytes + vptr:8 bytes + pad:5 bytes
B:16 bytes = A:16bytes - A's pad:5 bytes + char:3 bytes + pad:2 bytes

👏


최적화 과정에서 예상치 못하게 패딩을 복사하게된 걸 수도 있다.

memcpy는 객체가 potentially-overlapping이거나 trivially copyable가 아닌 경우 undefined한 결과를 얻게될 수 있다 되어있다.
-> potentially-overlapping경우에 base class subobject일 때가 포함돼있다.
-> potentially-overlapping 객체라 예상치 못한 결과가 나온 것일 수도 있다.

등등 다양한 의견들이 존재했다. 공식 문서에 적혀있는 내용은 아닌 것 같다.

profile
Hi!😁 I'm Soongle. Welcome to my Velog!!!

0개의 댓글