Sunday, November 29, 2009

Episode Twelve: When the Size *does* Matter

In C++, zero-sized addressable objects are forbidden. Objects must have size, even if they are empty. This is required in order to have different addresses for different objects. From the standard, 1.8.5:
A most derived object shall have a non-zero size and shall occupy one or more bytes of storage. Base class subobjects may have zero size.

An empty class is one that contain no non-static data members, either directly or indirectly. Empty classes shall have non-zero size as well, and usually occupy the size of a single char. However, in face of alignment, padding bytes may be added increasing the unused space.

The standard requires that the size of a complete object shall not be zero, and that base data members precede data members of the derived class. However, base class subobjects aren't required that; making it possible to remove the base class subobject from the derived object and thus avoiding the unused space.

While is possible to avoid the overhead of an empty class when using it as a base, it is not possible to do so with an empty data member. When holding a potentially empty data member, it would have to be moved as a base class in order to take advantage of EBO. Boost provides a ready to use utility called Compressed Pair [1]. Its very similar to std::pair, but if either of the template arguments are empty classes, then the "empty base-class optimization" is applied to compress the size of the pair.

[1] http://www.boost.org/libs/utility/compressed_pair.htm

No comments:

Post a Comment