c++sizeofchromium-embedded

Why use char padding[8]


template <typename T, typename U> class IsSubclass {
    typedef char YesType;
    struct NoType {
        char padding[8];
    };

    static YesType subclassCheck(U*);
    static NoType subclassCheck(...);
    static T* t;
public:
    static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType);
};

Why the size of the padding array should be 8 instead of other sizes?

I wish to know the reason for using 8


Solution

  • This seems to be outdated code. Since C++11, there is std::is_base_of. Also, this approach of writing a type trait using two overloads with different sizeof for their return types is rather old-fashioned. I could fill a whole answer to explain the history and evolution of how to write such a type trait. However, I think that is beyond the scope of this question.

    It works like this: The T* t; member is passed to the subclassCheck() member method. Either t can be implicitly converted to U*. This is the case when U is a public base class of T. Then YesType subclassCheck(U*); is called.

    If U is not a public base class of T, then t cannot be converted to U* and NoType subclassCheck(...); is called.

    value is the result of comparing the size of the return type of the called member function with the size of YesType. If they match, you know that YesType subclassCheck(U*); was called and that T inherits from U. Because sizeof is an un-evaluated context, no function is actually called (that's why it is OK to have only declarations, no definitions of the member functions).

    This only works when sizeof(NoType) is different from sizeof(YesType). What NoType actually contains is irrelevant as long as it makes sizeof(NoType) different from sizeof(char).

    There are many details that could be updated with newer C++ standards. typedef -> using. std::is_same rather than using sizeof to compare the types. And much more, but the whole approach is outdated. And also, C++11 introduced std::is_base_of.