2012-03-06 5 views
1

次のように沿って何か:窓64の_int64ビットフィールド

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

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

しかし、どういうわけかこの構造体のsizeofは、常に6バイトの代わりに8バイトを返します。任意のポインタは評価されていますか?

+1

'int 'のような' _int64'以外の型を使うとどうなりますか?コンパイラは、構造体が(2バイト境界ではなく)4バイトまたは8バイト境界でなければならないと判断する権利の範囲内にあります。パッキングはコンパイラのヒントにすぎません。 –

答えて

1

残念ながら、ビットフィールドは基底型のサイズを持ちます。この場合、_int64は8バイトです。

私が知っているどのコンパイラにも6バイトの整数がないので、より良い方法を見つける必要があります。 1つは16ビットと1つの32ビット値(または3つの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バイト単位で、 'high'と' low'の間に2バイトのパディングがあります。 –

+0

ありがとうございます。これはまさに、私が比較時に_int64を比較できることを知っているときに、複数の比較を行うのを避けたいものです。 –

+0

あなたは正しいです。しかし、3つの16ビット値の配列を使用している場合は、私も提案したように答えはOKです。しかし、比較式はやや複雑になります。 – Lindydancer

3

_int64を使用していますので、sizeofは8を返します。利用可能な64ビットのうち48ビットを使い切ったようです。我々はthis-

struct my_struct { 
    _int64 var1:1; 
} s; 
それでも

sizeofのようなものを宣言している場合でも、短い8.を言うでしょう、ビットフィールドの割り当ては、ビットフィールドの種類に応じて場所を取るでしょう。この場合、その_int64、したがって8バイトの割り当て。

+0

ありがとうPavan。私が_int64のように+、 - 、>、<などのようなフィールドで基本的な操作を行うことができるように、48ビットを使用する方法はありますか? –

+0

http://msdn.microsoft.com/en-us/library/aa261215(v = vs60).aspxが表示されている場合は、64ビット**符号なし整数**ビットフィールド型を作成することもできます。これを使って。通常の操作と同じようにすべての基本操作を実行できます。未使用の16ビットについて気にする必要はありません! –

+0

私はその部分を理解していますが、48ビットしか消費しない構造(または型)を持つ必要がありますが、基本的な操作では意味的に_int64のように使用できます。 ??? –

0

Google検索をしました。 __属性__((packed))を使用できるかもしれないことがわかった。あなたは異なる場合がありますウィンドウを使用していると述べたよう

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 

しかし、。

私は間違っている可能性があります。ありがとう。

ところで、私はまだこの質問に対する最良の解決策がわかりません。 構造体を使うと少し厄介なことになります(aの代わりにa._mを呼び出す必要があります)。しかし、少なくともuint64_tを使うよりも安全です。

+0

'packed'は、整列したメンバー間にパディングを挿入できるかどうかを制御します。メンバーの位置がずれてしまうことは許されません。基本的なビットフィールドの型は 'uint64_t'なので、依然として8バイトのアライメントが必要です。 –

関連する問題