C++ EBCO and [[no_unique_address]]
이 글의 핵심
EBCO and C++20 [[no_unique_address]] solving the problem of empty classes occupying memory. From std::tuple, std::unique_ptr implementation secrets, memory layout optimization to practical patterns.
Introduction: “Why does empty class occupy 1 byte?"
"Why is std::unique_ptr<T, Deleter> 16 bytes instead of 8 bytes?”
In C++, empty class (Empty Class—class without member variables) also occupies minimum 1 byte. This is because each object must have unique address. But this rule causes wasted memory when having stateless functors or custom deleters as members.
EBCO (Empty Base Class Optimization) is a compiler optimization where inheriting empty class as base makes size 0. C++20’s [[no_unique_address]] attribute allows applying this optimization to member variables too.
What This Guide Covers:
- Empty class rule: Why it occupies 1 byte
- EBCO principle: Size 0 when inherited as base class
- [[no_unique_address]]: C++20 member variable optimization
- Practical usage: std::tuple, std::unique_ptr, compressed pair
- Problem scenarios: When memory layout optimization is needed
- Complete examples: Custom smart pointer, compressed pair implementation
- Common errors: EBCO failure cases, ABI compatibility
- Production patterns: Standard library implementation techniques
1. Empty Class Rule and EBCO
Why Empty Class Occupies 1 Byte
C++ standard requires all objects have unique address. Even empty class needs minimum 1 byte for each array element to have different address.
struct Empty {};
int main() {
Empty e1, e2;
std::cout << sizeof(Empty) << '\n'; // 1
std::cout << &e1 << " vs " << &e2 << '\n'; // Different addresses
Empty arr[10];
std::cout << &arr[0] << " vs " << &arr[1] << '\n'; // 1 byte apart
}
Output:
1
0x7ffc1234 vs 0x7ffc1235
0x7ffc1240 vs 0x7ffc1241
Problem When Having as Member
struct Empty {};
struct Container {
int value; // 4 bytes
Empty empty; // 1 byte + 3 bytes padding (due to alignment)
// Total 8 bytes
};
static_assert(sizeof(Container) == 8);
Problem: Empty has no state but wastes 4 bytes (including padding).
EBCO: Size 0 When Inheriting as Base Class
EBCO (Empty Base Class Optimization) is compiler optimization making empty base class size 0.
// Type definition
struct Empty {};
struct Optimized : Empty {
int value; // 4 bytes
// Empty is size 0 → Total 4 bytes
};
static_assert(sizeof(Optimized) == 4);
Key: Base class is not array element so unique address rule is relaxed. Compiler places empty base at same address as derived class start to save space.
2. C++20 [[no_unique_address]]
Basic Usage
C++20 [[no_unique_address]] attribute allows applying EBCO to member variables.
struct Empty {};
struct Optimized {
int value; // 4 bytes
[[no_unique_address]] Empty empty; // 0 bytes
// Total 4 bytes
};
static_assert(sizeof(Optimized) == 4);
Comparison with EBCO
| Method | Syntax | Limitation |
|---|---|---|
| EBCO | Inherit as base | Inheritance required |
| [[no_unique_address]] | Member attribute | C++20 required |
Summary
Key Points
- Empty class: Occupies minimum 1 byte
- EBCO: Size 0 when inherited as base class
- [[no_unique_address]]: C++20 member optimization
- Use cases: Smart pointers, tuple, compressed pair
- Conditions: Empty type, no virtual functions
When to Use
✅ Use EBCO/[[no_unique_address]] when:
- Member is empty type
- Want to minimize memory
- Implementing smart pointers/containers
- Optimizing memory layout
❌ Don’t use when:
- Type has state
- Has virtual functions
- Adds unnecessary complexity
Best Practices
- ✅ Use for stateless functors
- ✅ Apply in custom smart pointers
- ✅ Use [[no_unique_address]] in C++20
- ❌ Don’t assume EBCO always applies
- ❌ Don’t forget ABI compatibility
Related Articles
Master EBCO for memory-efficient C++ code! 🚀
자주 묻는 질문 (FAQ)
Q. 이 내용을 실무에서 언제 쓰나요?
A. EBCO and C++20 [[no_unique_address]] solving the problem of empty classes occupying memory. From std::tuple, std::unique… 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.
Q. 선행으로 읽으면 좋은 글은?
A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.
Q. 더 깊이 공부하려면?
A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.
같이 보면 좋은 글 (내부 링크)
이 주제와 연결되는 다른 글입니다.
- C++ 메모리 정렬 | Alignment·Padding·False Sharing 완벽 정리
- C++ 캐시 효율적인 코드: 데이터 지향 설계 가이드
- C++ Pimpl Idiom 완벽 가이드 | 구현 은닉과 컴파일 시간 단축
이 글에서 다루는 키워드 (관련 검색어)
C++, EBCO, no_unique_address, memory-optimization, standard-library, empty-base, compressed-pair 등으로 검색하시면 이 글이 도움이 됩니다.