2012-03-06 7 views
1
나는 다음을 따라 등을 비교 뭔가를 같은 부호없는 정수를 사용할 수있는 구조의 6 바이트 (48 비트) 비트 필드 사용해야

: 윈도우 64에 든_int64 비트 필드

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

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

하지만를 이 구조체의 sizeof는 항상 6 바이트 대신 8 바이트를 반환합니다. 모든 포인터는 감사하니?

+1

'int'와 같이 '_int64'이외의 다른 유형을 사용하면 어떻게됩니까? 컴파일러는 구조가 4 바이트 또는 8 바이트로 정렬되어야한다고 결정할 권한이 있습니다 (2 바이트 정렬 대신). 패킹은 컴파일러에게 힌트 일뿐입니다. –

답변

1

불행히도, 비트 필드는 기본 유형의 크기를 가지며,이 경우 _int64는 8 바이트입니다.

내가 알고있는 컴파일러에는 6 바이트 정수가 없으므로 더 나은 방법을 찾아야합니다. 하나는 16 비트와 32 비트 값 (또는 3 개의 16 비트 값)을 사용하고 비교 함수를 작성하는 것입니다. 예를 들어

: 다른 많은 문제를 제공합니다 당신이 #pragma pack 필요하지 않습니다 보너스로서

struct my_struct 
{ 
    uint16_t high; 
    uint32_t low 
} s; 

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

.

+2

많은 시스템에서이 구조체는 8 바이트 단위이며, 'high'와 'low'사이에 2 바이트의 패딩이 있습니다. –

+0

답변 해 주셔서 감사합니다. 이것은 정확히 비교할 때 _int64를 비교할 수있을 때 다중 비교를 수행하지 않기를 원합니다. –

+0

당신 말이 맞아요. 그러나 세 개의 16 비트 값 배열을 사용하는 경우에는 대답에서 제안한대로 확인해야합니다. 그러나 비교 표현식은 다소 복잡 할 것입니다. – Lindydancer

3

_int64을 사용 했으므로 sizeof은 8을 반환합니다. 사용 가능한 64 비트 중에서 48 비트를 사용하기로 결정했습니다. 우리가 this-

struct my_struct { 
    _int64 var1:1; 
} s; 

뭔가를 선언하더라도 여전히 sizeof 짧은 8.이, 비트 필드의 할당이 비트 필드의 종류에 따라 일어날 것이라고 말할 것입니다. 이 경우에는 _int64이므로 8 바이트 할당입니다.

+0

감사합니다. Pavan. 48 비트 #를 사용하여 +, -,> 등의 필드에서 기본 작업을 수행 할 수 있도록하는 방법이 있습니까? 예를 들어 _int64에서하는 것처럼? –

+0

http : //msdn.microsoft.com/en-us/library/aa261215(v=60) .aspx가 표시되면 64 비트 ** 부호없는 정수 ** 비트 필드 형식을 만들 수 있으며 그걸 써. 일반 작업과 마찬가지로 모든 기본 작업을 수행 할 수 있습니다. 사용하지 않는 16 비트에 대해 걱정할 필요가 없습니다! –

+0

그 부분을 이해하지만 48 비트 만 사용하는 구조 (또는 유형)가 있어야하지만 의미 상 기본 동작에는 _int64와 같이 사용할 수 있습니다. ??? –

0

Google 검색을 한 적이 있습니다. __ 속성 ​​__ ((packed))을 사용할 수 있음을 알았습니다. 당신이 다를 수 있습니다 창을 사용하는 말했듯이

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 

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

하지만.

나는 잘못 될 수 있습니다. 감사.

아직,이 질문에 가장 적합한 해결책이 무엇인지 아직 모르겠습니다. 구조체를 사용하면 약간 어색함이 있습니다 (a 대신에 a._m을 호출해야합니다. 우리는 함께 할 수 있습니까?)하지만 적어도 uint64_t를 사용하는 것보다 안전합니다.

+0

'packed'는 정렬 된 멤버 사이에 패딩을 삽입 할 수 있는지 여부 만 제어합니다. 회원들이 잘못 정렬되는 것을 허용하지 않습니다. 기본 유형의 비트 필드는'uint64_t'이므로 8 바이트의 정렬이 필요합니다. –