Re: Packing of structure fields and whole structs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Let me make this concrete again.  With this test program:

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

char c = 1;
struct test t = { .a=2, .b=3 };

what can I assume about the alignment of t.a? As I now understand it, t.a and t.b both have alignment of 1, so t has alignment of 1, so t can be packed immediately after c with no gap. It is then unsafe (on some hardware) to take &t.a and pass it to a function that wants an int*.

What does gcc actually do? Well on x86, it does indeed pack t immediately after c:

	.file	"test2.c"
globl c
	.data
	.type	c, @object
	.size	c, 1
c:
	.byte	1
globl t
	.type	t, @object
	.size	t, 8
t:
	.long	2
	.long	3
	.ident	"GCC: (GNU) 4.1.2 20060920 (prerelease) (Debian 4.1.1-14)"
	.section	.note.GNU-stack,"",@progbits

On the other hand, on ARM it leaves a gap:

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


But, if I declare struct test like this:

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

then the ARM compiler generates the same layout as the x86 compiler, without the gap.

The practical consequence of this is that making the "harmless" change of moving the attribute from the members to the struct as a whole causes code that previously worked to not work. Would you say that such code was "always wrong", or is there an issue here?

Thanks for all the advice.


Phil.





[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux