xdevel2000
xdevel2000

Reputation: 21364

bit-field and storage unit

I have a doubt on my compiler using a 32 bit compiler (GCC MinGW) on a 64 bit machine. When I use this struct:

struct S 
{
    unsigned int a : 2; 
    unsigned int b : 3;
    unsigned int c : 4;
    _Bool d : 1;
} s;

sizeof s returns 8 so my compiler is using my machine word that's 8 byte (64 bit) for packing bit fields. Why if the compiler is 32 bit? In fact sizeof(int) give me 4.

Moreover if I declare my struct as:

struct S 
{
    char a; 
    char b;
    char c;
    _Bool d;;
} s;

sizeof s give me 4 so it is better to pack the structure in this way to save more space. So often is said that using bit field with structure can save space... but I think this is not always so... Am I missing some information?

Upvotes: 3

Views: 928

Answers (1)

Deduplicator
Deduplicator

Reputation: 45654

Bitfields are largely implementation-defined or even unspecified.

My guess is that switching from unsigned int to _Bool made your compiler start a completely new bit-field.

Anyway, you are right with the final resolution:
If you want something reliable and/or portable, pack them yourself.

Here all the relevant parts from C99+amendments (n1570).

6.7.2.1 Structure and union specifiers

[...]
5 A bit-field shall have a type that is a qualified or unqualified version of _Bool, signed int, unsigned int, or some other implementation-defined type. It is implementation-defined whether atomic types are permitted.
[...]
10 10 A bit-field is interpreted as having a signed or unsigned integer type consisting of the specified number of bits.125) If the value 0 or 1 is stored into a nonzero-width bit-field of type _Bool, the value of the bit-field shall compare equal to the value stored; a _Bool bit-field has the semantics of a _Bool.
11 An implementation may allocate any addressable storage unit large enough to hold a bitfield. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.
12 A bit-field declaration with no declarator, but only a colon and a width, indicates an unnamed bit-field.126) As a special case, a bit-field structure member with a width of 0 indicates that no further bit-field is to be packed into the unit in which the previous bitfield, if any, was placed.
[...]
15 Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.
[...]

Upvotes: 4

Related Questions