2012-03-06 55 views
1

我需要使用6個字節(48位)的位字段中的結構,即我可以使用作爲無符號整數進行比較等東西沿着以下:關於視窗64_int64位字段

pack (1) 
struct my_struct { 
    _int64 var1:48; 
} s; 

if (s.var >= 0xaabbccddee) { // do something } 

但不知,此結構的sizeof總是返回8個字節而不是6個字節。任何指針都讚賞?

+1

如果使用「_int64」以外的類型,比如「int」,會發生什麼?編譯器有權決定該結構必須是4字節或8字節對齊(而不是2字節對齊)。包裝僅僅是編譯器的一個提示。 – 2012-03-06 06:39:35

回答

1

不幸的是,一個位字段具有底層類型的大小,在這種情況下,_int64是8個字節。

由於在我知道的任何編譯器中沒有六個字節的整數,所以您將不得不尋找更好的方法。一種是使用一個16位和一個32位值(或三個16位值)並編寫自己的比較函數。

例如:

struct my_struct 
{ 
    uint16_t high; 
    uint32_t low 
} s; 

if ( (s.high > 0xaa) 
    || ( (s.high == 0xaa) 
     && (s.low >= 0xbbccddee))) 
{ ... do something ... } 

作爲獎勵,你不需要#pragma pack,這帶來了很多其他問題。

+2

在許多系統上,該結構將是一個8字節的單元,在「高」和「低」之間有2個字節的填充。 – 2012-03-06 06:45:37

+0

謝謝你的迴應。這正是我想要避免進行多重比較的時候,我知道_int64可以在比較中進行比較。 – 2012-03-06 06:48:34

+0

你說得對。但是,如果您使用三個16位值的數組,我也建議在答案中,您應該沒問題。不過,比較表達式會稍微複雜一些。 – Lindydancer 2012-03-06 07:54:09

3

您已使用_int64,因此sizeof返回8.它就像您已決定使用可用64位中的48位。即使我們聲明像這 -

struct my_struct { 
    _int64 var1:1; 
} s; 

不過sizeof會說8總之,位域的分配將根據位域的類型發生。在這種情況下,它的_int64因此分配8個字節。

+0

謝謝帕文。有沒有辦法使用48位#,以便我可以在+, - ,>,<等等字段上執行基本操作,就像我在_int64上做的一樣? – 2012-03-06 06:57:48

+0

如果您看到這個-http://msdn.microsoft.com/en-us/library/aa261215(v = vs.60).aspx,您也可以創建一個64位**無符號整數**位域類型,用它。您可以像正常一樣執行所有基本操作。你不需要打擾未使用的16位! – 2012-03-06 07:19:35

+0

我理解這個部分,但我需要一個只消費48位的結構(或類型),但在語義上可以像_int64一樣用於基本操作。 ??? – 2012-03-06 15:33:39

0

我做了一些谷歌搜索。發現你可能能夠使用__屬性__((打包))。

http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Type-Attributes.html

24 typedef struct __uint48_t uint48_t;            
    25 struct __attribute__((packed)) __uint48_t {          
    26  uint64_t _m:48;                
    27 };  

29 void test()                  
30 {                    
31  uint48_t a;                 
32  a._m = 281474976710655;              
33  printf("%llu", a._m);          
34  printf("%u", sizeof(a));             
35                     
36  a._m = 281474976710656;              
37  printf("%llu", a._m);              
38 }     

main1.c: In function ‘test’: 
main1.c:36:2: warning: large integer implicitly truncated to unsigned type [-Woverflow] 

$ ./a.out 
281474976710655 
6 
0 

但是,正如你說你使用的是Windows,這可能是不同的。

我可能是錯的,如果是的話就指出來。謝謝。

順便說一句,我仍然不知道什麼是這個問題的最佳解決方案。 使用struct會讓事情變得有點尷尬(你需要調用a._m而不是a,我們可以繞過它嗎?)但是至少它看起來比使用uint64_t更安全。

+0

'packed'只控制是否可以在對齊的成員之間插入填充。它不允許成員錯位。位域的底層類型是'uint64_t',所以它仍然需要8個字節的對齊。 – 2016-01-05 13:10:49