前往
大廳
主題

雞同鴨講3,sizeof範例補充

Yang | 2024-08-31 20:31:57 | 巴幣 0 | 人氣 79

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

參考資料:

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()
送禮物贊助創作者 !
0
留言

創作回應

相關創作

更多創作