In my first example I have two bitfields using int64_t
. When I compile and get the size of the class I get 8.
class Test
{
int64_t first : 40;
The C Standard's rules for bitfields aren't precise enough to tell programmers anything useful about the layout, but nonetheless deny implementations what might otherwise be useful freedoms.
In particular, bitfields are required to be stored within objects that are of the indicated types, or the signed/unsigned equivalent thereof. In your first example, the first bitfield must be stored in an int64_t or uint64_t object, and the second one likewise, but there's enough room for them to fit into the same object. In the second example, the first bitfield must be stored in an int64_t or uint64_t, and the second one in an int32_t or uint32_t. The uint64_t will have 24 bits that would be "stranded" even if additional bit fields were added to the end of the struct; the uint32_t has 8 bits which aren't presently used, but would be available for use of another int32_t or uint32_t bitfield whose width was less than 8 were added to the type.
IMHO, the Standard strikes just about the worst possible balance here between giving compilers freedom vs giving programmers useful information/control, but it is what it is. Personally I think bitfields would be much more useful if the preferred syntax let programmers specify their layout precisely in terms of ordinary objects (e.g. bitfield "foo" should be stored in 3 bits, starting at bit 4 (value of 16), of field "foo_bar") but I know of no plans to define such a thing in the Standard.