Josef “Jeff” Sipek

bool bitfield:1

This is the first of hopefully many posts related to interesting pieces of code I’ve stumbled across in the dovecot repository.

Back in 1999, C99 added the bool type. This is old news. The thing I’ve never seen before is what amounts to:

struct foo {
	bool	a:1;
	bool	b:1;
};

Sure, I’ve seen bitfields before—just never with booleans. Since this is C, the obvious thing happens here. The compiler packs the two bool bits into a single byte. In other words, sizeof(struct foo) is 1 (instead of 2 had we not used bitfields).

The compiler emits pretty compact code as well. For example, suppose we have this simple function:

void set(struct foo *x)
{
	x->b = true;
}

We compile it and disassemble:

$ gcc -c -O2 -Wall -m64 test.c
$ dis -F set test.o
disassembly for test.o

set()
    set:     80 0f 02           orb    $0x2,(%rdi)
    set+0x3: c3                 ret

Had we used non-bitfield booleans, the resulting code would be:

set()
    set:     c6 47 01 01        movb   $0x1,0x1(%rdi)
    set+0x4: c3                 ret

There’s not much of a difference in these simple examples, but in more complicated structures with many boolean flags the structure size difference may be significant.

Of course, the usual caveats about bitfields apply (e.g., the machine’s endian matters).

4 Comments »

  1. I thought bitfields were an anti-pattern for their lack of portability.

    Comment by Nur Hussein — September 14, 2016 @ 14:23

  2. They are certainly an annoying thing to deal with when it comes to data that comes from disk or over the network. (Yay, endian issues!) But for structures that reside in memory, I'm not aware of any portability issues.

    Comment by JeffPC — September 14, 2016 @ 15:12

  3. What about compiling the same code on a different architecture?

    Comment by Nur Hussein — September 14, 2016 @ 15:17

  4. Sure, the exact memory layout may be different then - but that only matters if you share that blob of memory with a different system...either by network or by writing to disk and moving the disk over. If that structure only ever lives in memory, then it doesn't matter how exactly it is laid out.

    I suppose if you write fragile code that assumes a certain memory layout then you may get a surprise - but that's no different than assuming that you are on a certain endian system regardless of bitfields.

    Comment by JeffPC — September 14, 2016 @ 15:21

Atom feed for comments on this post.

Leave a comment

Powered by blahgd