다음 세 가지를 고려하십시오 struct
.
class blub {
int i;
char c;
blub(const blub&) {}
};
class blob {
char s;
blob(const blob&) {}
};
struct bla {
blub b0;
blob b1;
};
int
4 바이트 인 일반 플랫폼에서 크기, 정렬 및 총 패딩 1 은 다음과 같습니다.
struct size alignment padding
-------- ------ ----------- ---------
blub 8 4 3
blob 1 1 0
bla 12 4 6
크기 1 이 원칙적으로 패딩에 "적합"할 수 있지만, 부재 blub
와 blob
부재 의 보관 사이에는 겹침이 없다 .blob
blub
C ++ 20은 no_unique_address
속성을 도입하여 인접한 빈 멤버가 동일한 주소를 공유 할 수 있도록합니다. 또한 한 멤버의 패딩을 사용하여 다른 멤버를 저장하는 위에서 설명한 시나리오를 명시 적으로 허용합니다. 에서 cppreference (강조 광산) :
이 데이터 멤버가 해당 클래스의 다른 모든 비 정적 데이터 멤버와 다른 주소를 가질 필요는 없음을 나타냅니다. 즉, 멤버에 빈 유형 (예 : 상태 비 저장 할당 자)이 있으면 컴파일러는 빈베이스 인 것처럼 공간을 차지하지 않도록 최적화 할 수 있습니다. 멤버가 비어 있지 않은 경우 다른 데이터 멤버를 저장하기 위해 테일 패딩을 재사용 할 수도 있습니다.
실제로이 속성을 on으로 사용하면 drop blub b0
의 크기가 bla
로 변경 8
되므로 godbolt에 표시된대로blob
실제로 저장됩니다 .blub
마지막으로, 우리는 내 질문에 도달합니다.
no_unique_address
사소하게 복사 할 수없는 객체 에 대해 표준의 어떤 텍스트 (C ++ 11에서 C ++ 20까지)로이 겹침을 방지 할 수 있습니까?
TC 객체의 std::memcpy
경우 멤버 하위 객체를 포함하여 한 객체에서 다른 객체로 이동할 수 있으므로 스토리지가 겹치면 스토리지의 전체 또는 일부가 손상되므로 TC 객체를 위에서 제외해야합니다. 인접한 멤버를 덮어 씁니다.) 2 .
1 패딩은 단순히 구조 크기와 모든 구성 멤버의 크기 차이를 재귀 적으로 계산합니다.
2 할 : 나는 복사 생성자가 정의한 이유입니다 blub
및 blob
하지 하찮게 복사 가능한 .