[ACCEPTED]-Union and struct packing problem-packing
Your struct has only 31 bits
0
AFAIK, the order in which the bits in the 16 struct are stored is undefined by the C99 15 standard (and the C89 standard too). Most 14 likely, the bits are in the reverse order 13 from what you expected.
You should have shown 12 the result you got as well as the result 11 you expected - it would help us with the 10 diagnosis. The compiler you use and the 9 platform you run on could also be significant.
On 8 MacOS X 10.4.11 (PowerPC G4), this code:
#include <inttypes.h>
#include <stdio.h>
typedef union
{
uint32_t raw;
struct
{
unsigned int present:1;
unsigned int rw:1;
unsigned int user:1;
unsigned int dirty:1;
unsigned int free:7;
unsigned int frame:20;
};
} page_union_t;
int main(void)
{
page_union_t p = { .raw = 0 }; //.....
unsigned trg_page = 0xA5A5A;
unsigned user = 1;
unsigned rw = 1;
unsigned present = 1;
p.frame = trg_page;
p.user = user;
p.rw = rw;
p.present = present;
printf("p.raw = 0x%08X\n", p.raw);
p.raw = trg_page<<12 | user<<2 | rw<<1 | present;
printf("p.raw = 0x%08X\n", p.raw);
p.raw <<= 1;
printf("p.raw = 0x%08X\n", p.raw);
return(0);
}
produces 7 the results shown:
p.raw = 0xE014B4B4
p.raw = 0xA5A5A007
p.raw = 0x4B4B400E
With the order of the 6 fields reversed, the result is more nearly 5 explicable:
#include <inttypes.h>
#include <stdio.h>
typedef union
{
uint32_t raw;
struct
{
unsigned int frame:20;
unsigned int free:7;
unsigned int dirty:1;
unsigned int user:1;
unsigned int rw:1;
unsigned int present:1;
};
} page_union_t;
int main(void)
{
page_union_t p = { .raw = 0 }; //.....
unsigned trg_page = 0xA5A5A;
unsigned user = 1;
unsigned rw = 1;
unsigned present = 1;
p.frame = trg_page;
p.user = user;
p.rw = rw;
p.present = present;
printf("p.raw = 0x%08X\n", p.raw);
p.raw = trg_page<<12 | user<<2 | rw<<1 | present;
printf("p.raw = 0x%08X\n", p.raw);
p.raw <<= 1;
printf("p.raw = 0x%08X\n", p.raw);
return(0);
}
This gives the result:
p.raw = 0xA5A5A00E
p.raw = 0xA5A5A007
p.raw = 0x4B4B400E
The first 4 result has an E as the last hex digit because 3 the least significant bit is not used, because 2 the bit-field structure has only 31-bits 1 defined..
If the exact position of bits matters, your 3 safest bet is explicit packing and unpacking 2 of the structure into an unsigned char array. Anything 1 else is too implementation dependent.
For reference to anyone who might find this, try 1 the packed attribute:
struct __attribute__((packed)){
}
You don't mention that you are clearing 3 out the bits of the structure beforehand, are 2 you sure you aren't ending up with garbage 1 bits left over in the first case?
// maybe try this
page_union_t p = {0};
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.