接續前一篇,C語言列舉(enum)成員的走訪與避免被誤改,補充紀錄sizeof範例

參考資料:
https://stackoverflow.com/questions/9439240/sizeof-class-with-int-function-virtual-function-in-c
https://stackoverflow.com/questions/34179352/why-the-sizeofd-increased-by-8-bytes-in-vs2015-when-i-derived-d-from-a-virtual
https://stackoverflow.com/questions/22113519/size-of-class-with-virtual-function

class UTestSizeOfRecordWithoutVirtual
{
    protected:
    template<int N>
    struct StaticRec
    {
        static constexpr int Value = N;

        const int GetValue1() const { return Value; };
        int GetValue2() { return GetValue1(); };
    };

    struct Static5: StaticRec<5>
    {
        const int GetValue3() const { return Value; };
    };

    struct Static5B: Static5
    {
        const int GetValue4() const { return GetValue3(); };
    };

    struct Static5C: Static5B
    {
        int Value2 = Value;
    };

    static constexpr size_t SizeOfStaticRec0 = sizeof(StaticRec<0>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRecM1 = sizeof(StaticRec<-1>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRecM5 = sizeof(StaticRec<-5>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRec1 = sizeof(StaticRec<1>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRec5 = sizeof(StaticRec<5>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5 = sizeof(Static5) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5B = sizeof(Static5B) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5BVaule = sizeof(Static5B::Value) == 4 ? 4 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5C = sizeof(Static5C) == 4 ? 4 : throw std::logic_error("");
};

class UTestSizeOfRecordWithVirtual
{
    protected:
    template<int N>
    struct StaticRec
    {
        static constexpr int Value = N;

        const int GetValue1() const { return Value; };
        int GetValue2() { return GetValue1(); };
    };

    struct Static5: StaticRec<5>
    {
        virtual const int GetValue3() const { return Value; };
    };

    struct Static5B: Static5
    {
        virtual const int GetValue4() const { return GetValue3(); };
    };

    struct Static5C: Static5B
    {
        int Value2 = Value;
    };

    static constexpr size_t SizeOfStaticRec0 = sizeof(StaticRec<0>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRecM1 = sizeof(StaticRec<-1>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRecM5 = sizeof(StaticRec<-5>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRec1 = sizeof(StaticRec<1>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRec5 = sizeof(StaticRec<5>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5 = sizeof(Static5) == 8 ? 8 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5B = sizeof(Static5B) == 8 ? 8 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5BVaule = sizeof(Static5B::Value) == 4 ? 4 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5C = sizeof(Static5C) == 16 ? 16 : throw std::logic_error("");
};

參考資料其實有看沒有懂,但是範例程式碼有無virtual,對於sizeof(Static5C)的影響會很大,難以理解

而且範例程式碼在不同平台(Windows/Linux/AIX7/...?)上結果一樣!很神奇

總之,團隊開發或是有甲乙方不同腳色的專案開發,別認為在改版時,

只是為struct或class內方法加上virtual,或是移除virtual,

不會對其他開發成員造成影響,其實有可能是埋地雷引發災難!

20240908補充
加上pragma pack(1),sizeof(Static5C)會變成12
pragma pack(8),sizeof(Static5C)會變成16

#pragma pack(1)

class UTestSizeOfRecordWithVirtualAndPack1
{
    protected:
    template<int N>
    struct StaticRec
    {
        static constexpr int Value = N;

        const int GetValue1() const { return Value; };
        int GetValue2() { return GetValue1(); };
    };

    struct Static5: StaticRec<5>
    {
        virtual const int GetValue3() const { return Value; };
    };

    struct Static5B: Static5
    {
        virtual const int GetValue4() const { return GetValue3(); };
    };

    struct Static5C: Static5B
    {
        int Value2 = Value;
    };

    static constexpr size_t SizeOfStaticRec0 = sizeof(StaticRec<0>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRecM1 = sizeof(StaticRec<-1>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRecM5 = sizeof(StaticRec<-5>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRec1 = sizeof(StaticRec<1>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRec5 = sizeof(StaticRec<5>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5 = sizeof(Static5) == 8 ? 8 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5B = sizeof(Static5B) == 8 ? 8 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5BVaule = sizeof(Static5B::Value) == 4 ? 4 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5C = sizeof(Static5C) == 12 ? 12 : throw std::logic_error("");
};

#pragma pack()

#pragma pack(8)

class UTestSizeOfRecordWithVirtualAndPack8
{
    protected:
    template<int N>
    struct StaticRec
    {
        static constexpr int Value = N;

        const int GetValue1() const { return Value; };
        int GetValue2() { return GetValue1(); };
    };

    struct Static5: StaticRec<5>
    {
        virtual const int GetValue3() const { return Value; };
    };

    struct Static5B: Static5
    {
        virtual const int GetValue4() const { return GetValue3(); };
    };

    struct Static5C: Static5B
    {
        int Value2 = Value;
    };

    static constexpr size_t SizeOfStaticRec0 = sizeof(StaticRec<0>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRecM1 = sizeof(StaticRec<-1>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRecM5 = sizeof(StaticRec<-5>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRec1 = sizeof(StaticRec<1>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStaticRec5 = sizeof(StaticRec<5>) == 1 ? 1 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5 = sizeof(Static5) == 8 ? 8 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5B = sizeof(Static5B) == 8 ? 8 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5BVaule = sizeof(Static5B::Value) == 4 ? 4 : throw std::logic_error("");
    static constexpr size_t SizeOfStatic5C = sizeof(Static5C) == 16 ? 16 : throw std::logic_error("");
};

#pragma pack()

arrow
arrow
    創作者介紹
    創作者 Yang 的頭像
    Yang

    GNAySolution

    Yang 發表在 痞客邦 留言(0) 人氣()