This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Missed bitfield packing?


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]