1

As I understand it, Empty Base-Class Optimization (EBO) should take effect when my type derives from a base class that has no data members or virtual functions. Under GCC and Clang, this is not happening. Here is a sample:

struct EmptyClass { };

struct SmallerClass : public EmptyClass {
    long long int _x[2];
};

struct BiggerClass : public EmptyClass {
    SmallerClass _sc;
};

struct BiggestClass : public EmptyClass {
    BiggerClass _bc;
    SmallerClass _sc;
};

I fully expected the size of BiggestClass to be equal to the size of 4 long long ints (32), but I noticed in the debugger that it was actually 48. Examining the AST in Clang (clang++ -cc1 -std=c++14 -fdump-record-layouts) and GCC (g++ -std=c++14 -fdump-lang-all -c) both showed me that EmptyClass was taking space in each of the classes that included it (and for BiggestClass, it occurs twice).

Here's the Clang AST output:

*** Dumping AST Record Layout
         0 | struct EmptyClass (empty)
           | [sizeof=1, dsize=1, align=1,
           |  nvsize=1, nvalign=1]

*** Dumping AST Record Layout
         0 | struct SmallerClass
         0 |   struct EmptyClass (base) (empty)
         0 |   long long [2] _x
           | [sizeof=16, dsize=16, align=8,
           |  nvsize=16, nvalign=8]

*** Dumping AST Record Layout
         0 | struct BiggerClass
         0 |   struct EmptyClass (base) (empty)
         8 |   struct SmallerClass _sc
         8 |     struct EmptyClass (base) (empty)
         8 |     long long [2] _x
           | [sizeof=24, dsize=24, align=8,
           |  nvsize=24, nvalign=8]

*** Dumping AST Record Layout
         0 | struct BiggestClass
         0 |   struct EmptyClass (base) (empty)
         8 |   struct BiggerClass _bc
         8 |     struct EmptyClass (base) (empty)
        16 |     struct SmallerClass _sc
        16 |       struct EmptyClass (base) (empty)
        16 |       long long [2] _x
        32 |   struct SmallerClass _sc
        32 |     struct EmptyClass (base) (empty)
        32 |     long long [2] _x
           | [sizeof=48, dsize=48, align=8,
           |  nvsize=48, nvalign=8]

So it seems not only is BiggestClass larger than what I expected, BiggerClass gets the size hit as well. It looks like nesting the classes removes the optimization.

What is the reasoning behind this removal of optimization, and is there a way around it that lets me compose these types with a common (empty) ancestor?

cyberbisson
  • 382
  • 2
  • 9

0 Answers0