(/w/cpp/language/access "cpp/language/access")  
[ Constructors and member initializer lists ](/w/cpp/language/constructor
"cpp/language/constructor")  
[ Default member initializer
](/w/cpp/language/data_members#Member_initialization "cpp/language/data
members") (C++11)  
[ ` friend ` specifier ](/w/cpp/language/friend "cpp/language/friend")  
[ ` explicit ` specifier ](/w/cpp/language/explicit "cpp/language/explicit")  
[ Converting constructor ](/w/cpp/language/converting_constructor
"cpp/language/converting constructor")  
Special member functions  
[ Default constructor ](/w/cpp/language/default_constructor
"cpp/language/default constructor")  
[ Copy constructor ](/w/cpp/language/copy_constructor "cpp/language/copy
constructor")  
[ Move constructor ](/w/cpp/language/move_constructor "cpp/language/move
constructor") (C++11)  
[ Copy assignment operator ](/w/cpp/language/copy_assignment
"cpp/language/copy assignment")  
[ Move assignment operator ](/w/cpp/language/move_assignment
"cpp/language/move assignment") (C++11)  
[ Destructor ](/w/cpp/language/destructor "cpp/language/destructor")  
Inheritance  
[ Base and derived classes ](/w/cpp/language/derived_class
"cpp/language/derived class")  
**Empty base optimization (EBO)**  
[ Virtual member functions ](/w/cpp/language/virtual "cpp/language/virtual")  
[ Pure virtual functions and abstract classes ](/w/cpp/language/abstract_class
"cpp/language/abstract class")  
[ ` override ` specifier ](/w/cpp/language/override "cpp/language/override")
(C++11)  
[ ` final ` specifier ](/w/cpp/language/final "cpp/language/final") (C++11)  
  
[ [edit]
](https://en.cppreference.com/mwiki/index.php?title=Template:cpp/language/classes/navbar_content&action=edit)

Allows the size of an empty base subobject to be zero.

##  Contents

  * 1  Explanation 
  * 2  Notes 
  * 3  References 
  * 4  External links 

  
---  
  
###  [ [ edit ](/mwiki/index.php?title=cpp/language/ebo&action=edit&section=1
"Edit section: Explanation") ]  Explanation

The size of any [ object ](/w/cpp/language/object "cpp/language/object") or
member subobject is required to be at least 1 even if the type is an empty [
class type ](/w/cpp/language/class "cpp/language/class") (that is, a class or
struct that has no non-static data members),  (unless with ` [[ [
no_unique_address ](/w/cpp/language/attributes/no_unique_address
"cpp/language/attributes/no unique address") ]] ` , see below)  (since C++20)
in order to be able to guarantee that the addresses of distinct objects of the
same type are always distinct.

However, base class subobjects are not so constrained, and can be completely
optimized out from the object layout:

Run this code

    
    
    struct Base {}; // empty class
     
    struct Derived1 : Base
    {
        int i;
    };
     
    int main()
    {
        // the size of any object of empty class type is at least 1
        static_assert(sizeof(Base) >= 1);
     
        // empty base optimization applies
        static_assert(sizeof(Derived1) == sizeof(int));
    }

Empty base optimization is prohibited if one of the empty base classes is also
the type or the base of the type of the first non-static data member, since
the two base subobjects of the same type are required to have different
addresses within the object representation of the most derived type.

A typical example of such situation is the naive implementation of  [
std::reverse_iterator ](/w/cpp/iterator/reverse_iterator "cpp/iterator/reverse
iterator") (derived from the empty base  [ std::iterator
](/w/cpp/iterator/iterator "cpp/iterator/iterator") ), which holds the
underlying iterator (also derived from  [ std::iterator
](/w/cpp/iterator/iterator "cpp/iterator/iterator") ) as its first non-static
data member.

Run this code

    
    
    struct Base {}; // empty class
     
    struct Derived1 : Base
    {
        int i;
    };
     
    struct Derived2 : Base
    {
        Base c; // Base, occupies 1 byte, followed by padding for