What does an unnamed zero length bit-field mean in C? [duplicate] What does an unnamed zero length bit-field mean in C? [duplicate] c c

What does an unnamed zero length bit-field mean in C? [duplicate]


As the document you linked explains right before:

A bit-field and an adjacent non-bit-field member are in separate memory locations. The same applies to two bit-fields, if one is declared inside a nested structure declaration and the other is not, or if the two are separated by a zero-length bit-field declaration, or if they are separated by a non-bit-field member declaration

It is a way to tell the compiler that b and c can/will be in the same memory location whereas d must be separate from them and can be modified concurrently to b/c


First of all, let's see chapter §6.7.2.1, Structure and union specifiers, P11. It says,

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. [...]

But, in case, we explicitly want two consecutive bit-field members, which "might be" packed into a single memory location to reside on separate memory location (i.e., addressable storage unit ), the above is the way to force it.

The next paragraph, P12, mentions,

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 bit-field, if any, was placed.

following your example, this makes sure that the two bit-field members surrounding the :0 will be residing in separate memory location (not inside a single addressable storage unit, even if sufficient memory remains to pack them into one). This has the similar effect of having a non-bit-field member in between two bit-fields, to force the separation of the memory location.

Quoting C11, chapter §3.14, NOTE 2 (emphasis mine)

A bit-field and an adjacent non-bit-field member are in separate memory locations. The same applies to two bit-fields, if one is declared inside a nested structure declaration and the other is not, or if the two are separated by a zero-length bit-field declaration, or if they are separated by a non-bit-field member declaration.

Also, regarding the usage ("why it is needed" part)

[...] The bit-fields b and c cannot be concurrently modified, but b and a, for example, can be.


Addendum:

Regarding the concurrency part, from NOTE 1

Two threads of execution can update and access separate memory locations without interfering with each other.

and, from chapter §5.1.2.4/P1,

Under a hosted implementation, a program can have more than one thread of execution (or thread) running concurrently. [...]

So, this is a theoretically viable option, as per the standard.


It's a way of ensuring that bit-fileds, that might otherwise be combined into a single memory location, are not.

For example, let's say you have an 8-bit character but you wanted to ensure your two 3-bit fields were at separate locations (and thus could be modified concurrently). To achieve that, you could use:

struct xyzzy {    int first  : 3,               : 0,    int second : 3;};

and you wouldn't have to worry about filling out the space manually, such as with junk : 5.

For the language lawyers, C11 3.14 memory location /3 states (my emphasis):

A bit-field and an adjacent non-bit-field member are in separate memory locations. The same applies to two bit-fields, if one is declared inside a nested structure declaration and the other is not, or if the two are separated by a zero-length bit-field declaration, or if they are separated by a non-bit-field member declaration.