_int64 битовое поле - PullRequest
       19

_int64 битовое поле

1 голос
/ 06 марта 2012

Мне нужно использовать 6-битное (48-битное) битовое поле в структуре, которую я могу использовать как целое число без знака для сравнения и т. Д., Что-то вроде следующего:

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

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

Но как-то в Windows 64,sizeof этой структуры всегда возвращает 8 байтов вместо 6 байтов.Любые указатели ценятся?

Ответы [ 3 ]

3 голосов
/ 06 марта 2012

Вы использовали _int64 и, следовательно, sizeof возвращает 8. Как будто вы решили использовать 48 бит из доступных 64 бит. Даже если мы объявим что-то вроде этого -

struct my_struct {
  _int64 var1:1;
} s;

Тем не менее sizeof скажет 8. Короче говоря, распределение битовых полей будет происходить в соответствии с типом битового поля. В этом случае его _int64 и, следовательно, 8 байтов.

1 голос
/ 06 марта 2012

К сожалению, битовые поля имеют размер базового типа, в данном случае _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, что приносит много других проблем.

0 голосов
/ 08 ноября 2012

Я сделал поиск в Google.Выяснилось, что вы можете использовать атрибут __ __ ((упакованный)).

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

Но, как вы сказали, вы используете окна, которые могут отличаться.

Я могу ошибаться, если это так, просто укажите это,Благодарю.

Кстати, я до сих пор не знаю, как лучше всего решить этот вопрос.Использование struct делает вещи немного неловкими (вам нужно вызвать a._m вместо a, мы могли бы обойтись с этим?) Но, по крайней мере, это кажется более безопасным, чем просто использование uint64_t.

...