2013-06-11 40 views
3

我想定義一個枚舉小於一個字節,同時保持類型安全。定義一個小於一個字節的枚舉/爲什麼這個結構大於一個字節?

定義枚舉爲:

enum MyEnum : unsigned char 
{ 
    i ,j, k, w 
}; 

我可以將它縮小到一個字節,但是我想使它只使用2位,因爲我會在最有它的4個值。這可以做到嗎?

在我的結構,我用枚舉,下面不工作

struct MyStruct 
{ 
    MyEnum mEnum : 2; // This will be 4 bytes in size 
}; 

謝謝!

更新:

的問題來自於這樣的場景:

enum MyEnum : unsigned char 
{ 
    i ,j, k, w 
}; 

struct MyStruct 
{ 
    union 
    { 
     signed int mXa:3; 
     unsigned int mXb:3; 
    }; 

    union 
    { 
     signed int mYa:3; 
     unsigned int mYb:3; 
    }; 

    MyEnum mEnum:2; 
}; 

的sizeof(MYSTRUCT)是顯示9個字節。理想情況下,我希望結構的大小爲1個字節。

更新實施的解決方案:

這個結構是一個字節,並提供相同的功能和類型安全:

enum MyEnum :unsigned char 
{ 
    i,j,k,w 
}; 

struct MyStruct 
{ 
    union 
    { 
     struct { MyEnum mEnum:2; char mXa:3; char mXb:3;}; 
     struct { MyEnum mEnum:2; unsigned char mYa:3; unsigned char mYb:3;}; 
    }; 
}; 
+4

都能跟得上。最好的選擇是使用位域,但在C++中,本身不能少於一個字節。 – 2013-06-11 21:00:40

+0

你究竟想要解決什麼問題?給出一些背景可能有助於揭示設計缺陷或更好的解決方案。 –

+0

我試圖儘可能地縮小結構以應對挑戰,我不明白爲什麼它不能完成,因此結構不會超過1個字節。 – mrantifreeze

回答

1

如果位域使用相同的基礎類型,它們只能共享空間。而任何未使用的位實際上都未被使用;如果unsigned int位字段中的位的總和是3位,則仍然需要4個字節總計。由於這兩個枚舉都有unsigned int成員,它們都是4個字節,但由於它們是位域,所以它們有一個對齊。所以第一個enum是4個字節,第二個是4個字節,那麼MyEnum是1個字節。由於所有這些都有一個對齊,所以不需要填充。

不幸的是,union實際上並不真正適用於位域。位字段僅用於整數類型。我能得到你的數據,而無需重新設計嚴重最多的是3個字節:http://coliru.stacked-crooked.com/view?id=c6ad03c93d7893ca2095fabc7f72ca48-e54ee7a04e4b807da0930236d4cc94dc

enum MyEnum : unsigned char 
{ 
    i ,j, k, w 
}; 

union MyUnion 
{ 
    signed char ma:3; //char to save memory 
    unsigned char mb:3; 
}; 

struct MyStruct 
{ 
    MyUnion X; 
    MyUnion Y; 
    MyEnum mEnum; 
}; //this structure is three bytes 

在完全重新設計類別中,你有這樣的:http://coliru.stacked-crooked.com/view?id=58269eef03981e5c219bf86167972906-e54ee7a04e4b807da0930236d4cc94dc

+0

對於快速讀者,你應該提到代碼不能編譯。 – PlasmaHH

+0

@PlasmaHH哦,是的,我在'MyStruct'中輸入了錯誤。 –

0

位打包 '對我的作品'

#include <iostream> 

enum MyEnum : unsigned char 
{ 
    i ,j, k, w 
}; 
struct MyStruct 
{ 
    MyEnum mEnum : 2; 
    unsigned char val : 6; 
}; 

int main() 
{ 
    std::cout << sizeof(MyStruct); 
} 

打印出來1.如何/你在測量什麼?

編輯:Live link

你在做的事情就像有一個指針在struct接下來的事情?在這種情況下,由於大多數32位系統上的指針必須與4個字節對齊,所以會產生30位死區。

編輯:有了您的更新爲例,其工會被打破你

enum MyEnum : unsigned char 
{ 
    i ,j, k, w 
}; 


struct MyStruct 
{ 
    unsigned char mXb:3; 
    unsigned char mYb:3; 

    MyEnum mEnum:2; 
}; 

有大小1.我不知道如何工會和位打包工作,雖然在一起,所以我沒有更多的幫助。

+0

我已更新問題以顯示用例 – mrantifreeze

+0

查看最新的編輯 - 它正在打破你的工會。 –

+0

位封裝僅適用於整型。工會不是整體類型。很遺憾,他們根本就不會努力工作。 :( –

1

編號C++將「char」定義爲平臺內存的最小可尋址單元。你不能尋址2位。

4

按照標準定義,類型sizeof必須至少爲1個字節。這是最小的可尋址內存單元。

你提位域的功能允許定義結構的成員具有更小的尺寸,但結構本身可能不是因爲

  • 它必須至少有1個字節的太
  • 對齊注意事項可能需要的是更大的

此外,您可能無法取位成員的地址,因爲上面說,一個字節是內存的最小可尋址單元(你已經可以看到,通過sizeof ACTU同盟返回的字節數,而不是位,所以如果你期望不到CHAR_BIT位,sizeof甚至不能表達它)。

+0

當然,但我不太清楚爲什麼當(在我更新的問題中)現在enum是一個有點結構的struct的成員,其大小膨脹了很大。 – mrantifreeze

+0

@mrantifreeze:我不知道你究竟是什麼意思是「bit packed struct」,但也許你正在尋找編譯器擴展,比如gccs'[[packed]]'屬性?我假設大多數編譯器都給出了union的unsigned/signed的對齊要求,這會使填充3次無符號= 12個字節 – PlasmaHH

+0

@PlasmaHH:小心,他的工會有一個'sizeof(4)',但只有一個對齊方式:D –

相關問題