struct s { char a:4; char b:8; char c:4; } __attribute__ ((packed)) is 3 bytes long because b gets pushed to the next byte boundary.
You would think that similarly: struct t { char a:4; short b:16; char c:4; } __attribute__ ((packed)) would come out to be 4 bytes long. However, that's not the case because here, b gets bit-packed. The reason for this behavior is that finish_struct does not propagate packed to fields whose type has alignment <= BITS_PER_UNIT: for (x = fieldlist; x; x = TREE_CHAIN (x)) { if (TREE_TYPE (x) == error_mark_node) continue; DECL_CONTEXT (x) = t; if (TYPE_PACKED (t) && TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT) DECL_PACKED (x) = 1; Is this intentional or an oversight? Shouldn't the alignment check be disregarded for DECL_BIT_FIELDs? Also note that extend.texi seems to be pretty clear about packed bitfields: @item packed @cindex @code{packed} attribute The @code{packed} attribute specifies that a variable or structure field should have the smallest possible alignment---one byte for a variable, and one bit for a field, unless you specify a larger value with the @code{aligned} attribute. Adam