Reputation: 21
I need to use a 6-byte (48-bit) bitfield in a structure that I can use as unsigned integer for comparison etc. Something along the following:
pack (1)
struct my_struct {
_int64 var1:48;
} s;
if (s.var >= 0xaabbccddee) { // do something }
But somehow on 64-bit Windows, sizeof
this struct always returns 8 bytes instead of 6 bytes. Any pointers are appreciated?
Upvotes: 1
Views: 4164
Reputation: 1139
I did some google search. Found out you might be able to use __attribute__((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
But, as you said you are using Windows, which might be different.
I could be wrong, if so just point it out.
BTW, I still do not know what is the best solution to this question.
Using struct makes thing a little awkward (you need call a._m
instead of a
, could we get round with it?) But at least it seems safer than just using uint64_t
.
Upvotes: -1
Reputation: 28525
You have used _int64
and hence sizeof
returns 8. Its like you've decided to use up 48 bits out of the available 64 bits. Even if we declare something like this-
struct my_struct {
_int64 var1:1;
} s;
Still sizeof
would say 8. In short, allocation of bitfields would take place according to the type of the bitfield. In this case its _int64
and hence 8 bytes allocation.
Upvotes: 3
Reputation: 26094
Unfortunately, a bit filed have the size of the underlying type, in this case an _int64 is 8 bytes.
As there is no six byte integers in any compiler that I know of, you would have to find a better way. One is to use one 16 and one 32 bit value (or three 16 bit values) and write your own comparison function.
For example:
struct my_struct
{
uint16_t high;
uint32_t low
} s;
if ( (s.high > 0xaa)
|| ( (s.high == 0xaa)
&& (s.low >= 0xbbccddee)))
{ ... do something ... }
As a bonus you don't need #pragma pack
, which brings a lot of other problems.
Upvotes: 2