43

If the size of an empty class can't be 0, what magic is doing std::tuple so the sizeof of unique_ptr is returning 8 in a 64 bit machine?

In unique_ptr the member is defined as:

  typedef std::tuple<typename _Pointer::type, _Dp>  __tuple_type;                 
  __tuple_type  _M_t;

Where _Dp is the deleter class.

Compiler is gcc version 4.7.1 (Debian 4.7.1-7)

piotr
  • 5,657
  • 1
  • 35
  • 60

2 Answers2

62

The reason is that the typename _Dp = default_delete<_Tp> is an empty class and the tuple template employs empty base class optimization.

If you instantiate the unique_ptr with a non-default delete, you should see the size increase.

chill
  • 16,470
  • 2
  • 40
  • 44
  • 14
    To rephrase a little: when instantiated by itself, a class must have non-zero size, but when instatiated as a base class, zero size is allowed. – Jerry Coffin Nov 19 '12 at 19:58
  • 5
    Not really true: I instantiated with my own defined deleter, and got an `unique_ptr` with the size of a pointer. All it needs is the deleter to have a "natural size" of zero. – lvella Jul 06 '18 at 18:26
40

unique_ptr as specified can have zero overhead because the only thing needed to implement it is to modify the process of copying/moving a raw pointer; no additional information is necessary. Therefore unique_ptr doesn't need to store anything besides the pointer and can be the same size as a pointer.

As to how your particular implementation, achieves that; Only most derived types need to have a size greater than zero. Empty base classes can take up zero bytes. It's quite common for standard library implementations to take advantage of the so-called 'empty base class' optimization for all kinds of things, from stateless allocators in containers to tuple.

bames53
  • 86,085
  • 15
  • 179
  • 244
  • Thanks for the answer, voted +1 I accepted chill as he has less score and also provided a valid answer. – piotr Nov 19 '12 at 19:48