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]

Packing of structure fields and whole structs


Dear GCC Experts,

I am trying to understand the subtleties of __attribute__((packed)). I have some code that works on x86, where unaligned accesses work, but fails on ARM where they do not.

As far as I can see, if I declare a struct with the packed attribute applied to the whole struct, like this:

struct test {
  int a;
  int b;
} __attribute__((packed));

and then use it like this:

{
  char c;
  struct test t;
}

Then t will be packed next to c, and t.a and t.b will be unaligned. This is not what I want!

There are lots of examples in the Linux kernel headers (if you have a source tree handy, grep for them). Here's one example picked at random:

#define FDDI_K_OUI_LEN	3
struct fddi_snap_hdr
	{
	__u8	dsap;					/* always 0xAA */
	__u8	ssap;					/* always 0xAA */
	__u8	ctrl;					/* always 0x03 */
	__u8	oui[FDDI_K_OUI_LEN];	/* organizational universal id */
	__be16	ethertype;				/* packet type ID field */
	} __attribute__ ((packed));

As far as I can see, making this packed can only cause trouble. If packed wasn't there there would still be no gaps between the fields - would there? - and variables of this type would be word-aligned, so the 16-bit field would be 16-bit aligned, and it would work on an ARM. But by declaring it as packed then a variable of this type will be packed at any alignment (e.g. char c; struct fddi_snap_hdr x;) and the 16-bit field may be unaligned.

Am I completely misunderstanding all of this?

I am using gcc 4.1.2.

Here is the test that I have been using to investigate this:

struct test {
  int a;
  int b;
}__attribute__((packed));
char c = 1;
struct test t = { .a=2, .b=3 };

arm-linux-gnu-gcc -S test.c

	.file	"test.c"
	.global	c
	.data
	.type	c, %object
	.size	c, 1
c:
	.byte	1
	.global	t
	.type	t, %object
	.size	t, 8
t:
	.4byte	2
	.4byte	3
	.ident	"GCC: (GNU) 4.1.2 20061028 (prerelease) (Debian 4.1.1-19)"


Many thanks in advance for any advice.


Regards,

Phil.

(you're welcome to Cc: any replies as I'm subscribed to the digest.)





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