Almost every aspect of bit fields is implementation-defined. Even the subscription of the "plain int " int is determined by the implementation; it may be signed or unsigned. The layout of the fields β regardless of whether they go from the most significant bit to the least significant bit in the containing βunitβ (the term used in the standard) or from the least significant β is the implementation. The size of the largest allowable bit field; when bit-bit is stored in a new block; all of this is determined by implementation.
For example, on Mac OS X 10.8.4 using GCC 4.8.1, you can demonstrate that the struct bitfield in the question is stated with a occupying the 3 least significant bits (bit 0-2), b occupying the next 13 bits (3-15) and c , occupying the following 1 bit (16):
#include <stdio.h> static void print_info(int v); int main(void) { int values[] = { 0x55555555, 0xAAAAAAAA, 0x87654321, 0xFEDCBA98, 0xFEDCBA90, 0xFEDCBA91, 0xFEDCBA92, 0xFEDCBA93, 0xFEDCBA94, 0xFEDCBA95, 0xFEDCBA96, 0xFEDCBA97, 0xFEDCBA98, 0xFEDCBAA0, 0xFEDCBAA8, 0x0000BAA0, 0x0001BAA0, 0x00000008, 0x00000010, 0x00000018, 0x0000FFF0, 0x0000FFF8, }; for (size_t i = 0; i < sizeof(values)/sizeof(values[0]); i++) print_info(values[i]); return 0; } static void print_info(int v) { union { unsigned int x; struct bitfield { signed int a:3; unsigned int b:13; unsigned int c:1; } y; } u; ux = v; printf("0x%.8X => %2d 0x%.4X %1X\n", ux, uya, uyb, uyc); }
Output Example:
0x55555555 => -3 0x0AAA 1 0xAAAAAAAA => 2 0x1555 0 0x87654321 => 1 0x0864 1 0xFEDCBA98 => 0 0x1753 0 0xFEDCBA90 => 0 0x1752 0 0xFEDCBA91 => 1 0x1752 0 0xFEDCBA92 => 2 0x1752 0 0xFEDCBA93 => 3 0x1752 0 0xFEDCBA94 => -4 0x1752 0 0xFEDCBA95 => -3 0x1752 0 0xFEDCBA96 => -2 0x1752 0 0xFEDCBA97 => -1 0x1752 0 0xFEDCBA98 => 0 0x1753 0 0xFEDCBAA0 => 0 0x1754 0 0xFEDCBAA8 => 0 0x1755 0 0x0000BAA0 => 0 0x1754 0 0x0001BAA0 => 0 0x1754 1 0x00000008 => 0 0x0001 0 0x00000010 => 0 0x0002 0 0x00000018 => 0 0x0003 0 0x0000FFF0 => 0 0x1FFE 0 0x0000FFF8 => 0 0x1FFF 0
Test values ββare not completely randomly selected. From the test values ββ0xFEDCBA90 to 0xFECBA97, we see that the least significant 3 bits contain a . From the test values ββ0x0000BAA0 and 0x0001BAA0, we see that the 17th bit (or bit 16) contains c . And from the test values ββfrom 0x00000008 to 0x0000FFF8, we see that bits 3-15 contain b .
However, it should be noted that the code is controversial and portable in theory; since the code is written in ux and then reads ux and uya , uyb and uyc , it does not refer to the last union member strictly adhering to undefined. In practice, this "always" works (I have not heard about a system where it does not work - it is unlikely, but it is technically impossible for a system to exist in which it does not work).
This layout is not the only possible layout for any part of the imagination. However, I do not have access to compilers or systems that demonstrate alternative layouts.
In ISO / IEC 9899: 2011, section Β§6.7.2.1, the Structure and Union Specification says:
ΒΆ11 An implementation can allocate any storage address block large enough to hold a bit field. If there is enough space left, a bit field that immediately follows another bit field in the structure should be packed into adjacent bits of the same block. If there is not enough space, then whether a bit field that does not fit will fit in the next block or overlap adjacent units is determined by the implementation. The order of distribution of bit fields within a unit (from high order to low or low order) is determined by the implementation. The alignment of the storage address block is not indicated.
ΒΆ12 Declaring a bit field without a declarator, but only a colon and a width, indicates an unnamed bit field. 126) As a special case, an element of the structure of a bit field with a width of 0 indicates that the additional bit field should not be packed in the block in which the previous bit field was placed, if any.
126) The structure element of an unnamed bit field is useful for filling to match external overlays.
A small version of the structure in question:
struct exegesis { signed int a:3; unsigned int :0; unsigned int b:13; unsigned int :0; unsigned int c:1; };
This structure has a size of 12 (on the same compiler / platform as before). The storage block for bit fields on this platform is 4 bytes, so anonymous zero-width fields start a new memory block. a is stored in the least significant 3 bits of the first 4-byte block; b in the least significant 13 bits of the second 4-byte block; and c in the lowest bit value of the third 4-byte block. As noted in the quote from the standard, you can have anonymous bit fields that are greater than 0.