Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Empty base optimization

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
       

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

      Contents

      [edit]Explanation

      The size of anyobject or member subobject is required to be at least 1 even if the type is an emptyclass type (that is, a class or struct that has no non-static data members),(unless with[[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 ofstd::reverse_iterator (derived from the empty basestd::iterator), which holds the underlying iterator (also derived fromstd::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 iint i;}; struct Derived3: Base{    Derived1 c;// derived from Base, occupies sizeof(int) bytesint i;}; int main(){// empty base optimization does not apply,// base occupies 1 byte, Base member occupies 1 byte// followed by 2 bytes of padding to satisfy int alignment requirements    static_assert(sizeof(Derived2)==2*sizeof(int)); // empty base optimization does not apply,// base takes up at least 1 byte plus the padding// to satisfy alignment requirement of the first member (whose// alignment is the same as int)    static_assert(sizeof(Derived3)==3*sizeof(int));}

      Empty base optimization isrequired forStandardLayoutTypes in order to maintain the requirement that the pointer to a standard-layout object, converted usingreinterpret_cast, points to its initial member, which is why the requirements for a standard layout type include "has all non-static data members declared in the same class (either all in the derived or all in some base)" and "has no base classes of the same type as the first non-static data member".

      (since C++11)

      The empty member subobjects are permitted to be optimized out just like the empty bases if they use the attribute[[no_unique_address]]. Taking the address of such member results in an address that may equal the address of some other member of the same object.

      Run this code
      struct Empty{};// empty class struct X{int i;[[no_unique_address]] Empty e;}; int main(){// the size of any object of empty class type is at least 1    static_assert(sizeof(Empty)>=1); // empty member optimized out:    static_assert(sizeof(X)== sizeof(int));}
      (since C++20)

      [edit]Notes

      Empty base optimization is commonly used by allocator-aware standard library classes (std::vector,std::function,std::shared_ptr, etc) to avoid occupying any additional storage for its allocator member if the allocator is stateless. This is achieved by storing one of the required data members (e.g.,begin,end, orcapacity pointer for thevector) in an equivalent ofboost::compressed_pair with the allocator.

      In MSVC, empty base optimization is not fully compliant with the standard requirements (Why is the empty base class optimization (EBO) is not working in MSVC?).

      [edit]References

      • C++23 standard (ISO/IEC 14882:2024):
      • 7.6.10 Equality operators [expr.eq]
      • 7.6.2.5 Sizeof [expr.sizeof]
      • 11 Classes [class]
      • 11.4 Class members [class.mem]
      • C++20 standard (ISO/IEC 14882:2020):
      • 7.6.10 Equality operators [expr.eq]
      • 7.6.2.4 Sizeof [expr.sizeof]
      • 11 Classes [class]
      • 11.4 Class members [class.mem]
      • C++17 standard (ISO/IEC 14882:2017):
      • 8.10 Equality operators [expr.eq]
      • 8.3.3 Sizeof [expr.sizeof]
      • 12 Classes [class]
      • 12.2 Class members [class.mem]
      • C++14 standard (ISO/IEC 14882:2014):
      • 5.10 Equality operators [expr.eq]
      • 5.3.3 Sizeof [expr.sizeof]
      • 9 Classes [class]
      • 9.2 Class members [class.mem]
      • C++11 standard (ISO/IEC 14882:2011):
      • 5.10 Equality operators [expr.eq] (p: 2)
      • 5.3.3 Sizeof [expr.sizeof] (p: 2)
      • 9 Classes [class] (p: 4,7)
      • 9.2 Class members [class.mem] (p: 20)
      • C++98 standard (ISO/IEC 14882:1998):
      • 5.10 Equality operators [expr.eq] (p: 2)
      • 5.3.3 Sizeof [expr.sizeof] (p: 2)
      • 9 Classes [class] (p: 3)

      [edit]External links

      More C++ Idioms/Empty Base Optimization — A wikibook
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/ebo&oldid=182568"

      [8]ページ先頭

      ©2009-2025 Movatter.jp