1833018 Members
1999 Online
110048 Solutions
New Discussion

Re: Packed structures

 
Max_4
Frequent Advisor

Packed structures

Hi to all,

Consider the following packed structure:

struct bit_field
{
unsigned int field_a: 2;
unsigned int field_b: 3;
unsigned int field_c: 5;
} flags;


According to K&R book the language does not
define whether storage starts at the least significant or most
significant bit. It is strictly up to the individual compiler.


Then how do I know how the compiler I'm using behaves? Is there a programming trick to get this information out of my compiler?



Thanks to all in advance...

Manuel
8 REPLIES 8
Adam J Markiewicz
Trusted Contributor

Re: Packed structures

Generally speaking you shouldn't need to know this.
The problem could be bigger as the compiler is allowed even to insert padds between your fields (for example it is allowed to force all fields not to cross byte - boundary).

In your case it could add something before field_c to make it start at the next byte. So your structure could be:
struct bit_field
{
unsigned int field_a: 2;
unsigned int field_b: 3;
unsigned int compiler_added_invisible_pad: (8 - ( 3 + 2 ))
unsigned int field_c: 5;
} flags;

But if you're just curios how it is organised wirte the programm to check it.

int main( void ) {
union {
long l;
struct bit_field bf;
} u;

u.l = 0;
u.bf.field_a = (unsigned)-1;
printf( "field_a bitmask: %lx\n", u.l );
u.l = 0;
u.bf.field_b = (unsigned)-1;
printf( "field_b bitmask: %lx\n", u.l );
u.l = 0;
u.bf.field_c = (unsigned)-1;
printf( "field_c bitmask: %lx\n", u.l );

return 0;
}

However BEWARE!
If you make yse of this knowledge inside your code and decide to make changes... (upgrade compiler, change compiling options) you're on your own and nobody will help you.

Good luck

Adam
I do everything perfectly, except from my mistakes
Max_4
Frequent Advisor

Re: Packed structures

Thanks Adam for your explanation... and suggestion..

However I was wondering which the definition of struct bit_field would be?

I was not able to find it in the code snippet you posted...

Again thanks a lot for your help...


Manuel
Max_4
Frequent Advisor

Re: Packed structures

I'm sorry i got confused ....

Of course I've already created that structure in my question...
Silly of me... ;-)
I apologize...

I was wondering what those
casts of -1 to (unsigned) would do?

Again thanks a lot to Adam and to anyone who takes the time to help me...
Wodisch
Honored Contributor

Re: Packed structures

that cast fills your bitfields with all binary "1"s.
Adam J Markiewicz
Trusted Contributor

Re: Packed structures

Hi again.

Just, like Wodish said.

'-1' is very comfortable method of forcing all bits being set to 1.
Why did I use signed version and then used a cast? Because I'm lazy and I don't like bugs. :)

If you want char with all bits set to 1 you could count it carefully and write:
char all_1_c = 255;
However you could write also
char all_1_c = -1;

If you wanted short, you could do:
short all_1_s = 65535;
and also
short all_1_s = -1;

the same with long, and even more practical with non-common sizes as used in bitfields.

With the first solution if you decide to change the size after some time, from char to short you'll have to remember to recalculate the initialization:

char all_1 = 255; // I want it longer!

short all_1 = 255; // Oh, no! I forgot the second byte!

And belive me or not - if you have to remember plenty of such things you'll be lost at the second change of your code, so the best way is to make code when you have nothing to remember.

Then I made a cast, because your compiler could write a warning that I initialise unigned with negative. And belive me again, if you have warnings you'll get used to them and stop reading them. And sometimes they can save you a lot of work if you check them...


At the end - when I think about this I think that more readable form would be ~0 (with 'tylde' at the beginning), which means 'binary negated zero', which means 'all ones'. But '-1' is so commonly used that nobody cares... :)

Good luck

Adam
I do everything perfectly, except from my mistakes
Max_4
Frequent Advisor

Re: Packed structures

Thanks Wodisch for the input...

I assume that this comes from the fact that we're using 2s complement and -1 in a system where `int' will have four bytes
-1 will be represented as
0xffff. Just let me know if I'm correct.

Thanks again...
Adam J Markiewicz
Trusted Contributor

Re: Packed structures

Last words to make everything completely clear.

-1 in four-bytes representation is actually 0xffffffff (as one charcter in this representation stands for four bits).
Consequently 0xffff stands for two bytes.

Rest of your assumption is absolutelly correct.

Results from the code I've sent you is bit-mask, that is all bits for the field are set to '1', other are '0'. The results are written as hexadecimal number. The most comfortable would be to write it binary, but printf does not have an option to write binary. Only signed decimal, unsigned decimal, hexadecimal and octal.

So you'll recive something like (this can of course change depending on what you're about to check):
field_a bitmask: c0000000
field_a bitmask: 38000000
field_a bitmask: 7c00000

which you'll have to investigate further.

For your convenience:
h 1 = b 0001
h 2 = b 0010
h 4 = b 0100
h 8 = b 1000

h 3 = b 0011
h 6 = b 0110
h c = b 1100

h 7 = b 0111
h e = b 1110
h f = b 1111


Good luck

Adam
I do everything perfectly, except from my mistakes
Max_4
Frequent Advisor

Re: Packed structures

Hello Adam,

Thanks a lot again for your help...
Your good and detailed explanation has made things a whole lot easier to understand...

I appreciate it...


Manuel