Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Don't understand the bit field description from the C standard

Tags:

c

"Whether a field may overlap a word boundary is implementation-defined. Fields need not be named; unnamed fields (a colon and width only) are used for padding. The special width 0 may be used to force alignment at the next word boundary."

- The C programming Language [2e] by Kernighan & Ritchie [Section 6.9, p.150]

I'm unable to get these lines. Can you please explain?

like image 734
ashna Avatar asked Jan 22 '23 21:01

ashna


1 Answers

"whether a field may overlap a word bounday is implementation - defined.

Consider two words of memory, where the word size is say 32 bits:

[31] [30] [29] ... [2] [1] [0] | [31] [30] [29] ... [2] [1] [0]

If we had a struct:

struct X
{
    int a : 30;
    int b : 4;
};

Then a compiler might choose to put field b so part is in each word, or it might leave a gap so that all of b falls inside the second word:

[31] [30] [29] ... [2] [1] [0] | [31] [30] [29] [28] ... [2] [1] [0]
a--------------------a b-----------------b
OR
a--------------------a    GAP    b-----------------b

Why might it leave a GAP? Because then when it wants to read or write b, it only needs to work with one word in memory - that's typically faster and simpler, needing less CPU instructions.

fields need not be named; unnamed fields ( a colon and width only) are used for padding.

If we changed our earlier struct, we could explicitly ask for a gap:

struct X
{
    int a : 30;
    int   : 2;  // unnamed field
    int b : 4;
};

This is saying "leave 2 bits between a and b - they don't need an identifier (name) because I'll never ask what's in them, or need to ask their value be changed". But, you don't have to make it 2 just so that 30 + 2 == 32 (our word size)... you can ask for whatever gaps you like whereever you like. This might be useful if you're dealing with values from some hardware device, and you knew what some of the bits were but not others, or you just didn't need to use some of them - you can just leave them unnamed to document your disinterest while still having the compiler space the named bit fields at the required offsets into the word necessary to correspond to the hardware's usage.

the special width 0 may be used to force alignment at the next word boundary."

This just means the compiler can calculate how many bits are left in the partially-filled word, and skip to the start of the next word. Just as we ensured b started in a new word by adding a 2 bit field above (given our knowledge that a was 30 bits and the word size was 32), we could have...

struct X
{
    int a : 30;
    int   : 0;  // unnamed field
    int b : 4;
};

...and the compiler would work out the 2 for us. This way, if we change a to be some other size, or end up compiling for a 64-bit word size, the compiler will silently adjust to appropriate behaviour without needing the unnamed field to be manually corrected.

like image 196
Tony Delroy Avatar answered Jan 24 '23 10:01

Tony Delroy