user2380654
user2380654

Reputation:

Template specialization struct size

I'm experiencing an - at least to me - strange behavior when applying the sizeof operator to a template specialization. Consider these declarations:

#pragma pack(push, 1)

template <bool enable>
struct RGB_data {
    typedef unsigned char typeRGB;
    typeRGB R;
    typeRGB G;
    typeRGB B;
};
template <> struct RGB_data<false> {};

template <bool enable>
struct XYZ_data {
    typedef float type3D;
    type3D X;
    type3D Y;
    type3D Z;
};
template<> struct XYZ_data<false> {};

template <bool enable>
struct Alpha_data {
    typedef unsigned char typeAlpha;
    typeAlpha A;
};
template<> struct Alpha_data<false> {};

template <bool enable>
struct Confidence_data {
    typedef unsigned char typeConfidence;
    typeConfidence C;
};
template<> struct Confidence_data<false> {};


template <
    bool enableXYZ,
    bool enableRGB,
    bool enableC,
    bool enableA
>
struct Pixel :
    public XYZ_data<enableXYZ>,
    public RGB_data<enableRGB>,
    public Alpha_data<enableA>,
    public Confidence_data<enableC>
{};

typedef Pixel<true,false,false,false> Pixel3D;
typedef Pixel<true,false,true,false> Pixel3Dc;

#pragma pack(pop)

However, the size of the Pixel3Dc struct is 14 bytes; the size of Pixel3D is 14 bytes as well. The sizes of the data types in use are 1 and 4 for unsigned char and float, respectively.

Where are the additional bytes, and how can I achieve a struct size that matches with the size of the contained data?

Environment is VS 9.0, Windows7 x64, Compiled to 32Bit, Debug & Release mode.

Upvotes: 0

Views: 437

Answers (1)

James Kanze
James Kanze

Reputation: 153909

I don't have a solution, but at least part of the reason for extra bytes is that a type cannot have a size of 0; even an empty struct or class (e.g. like Alpha_data<false>) will have a size of at least one. On the other hand, you are deriving from them, so the empty base class optimization (which allows a base class to have an effective size of 0, even if sizeof reports more) should apply. Apparently, MSC is only applying it to one of the bases, probably the first. Otherwise, you'd get a size of 15.

Probably not much help to you, but g++ gives sizes of 12 and 13, which corresponds to applying the empty base class optimization to all of the bases.

Unless someone knows of an option to make MSC be more aggressive in applying the empty base class optimization, your options are to report this as a bug to Microsoft, hoping they'll be comprehensive (since the standard doesn't require that the empty base class optimization be used at all), or switch to g++.

Upvotes: 1

Related Questions