Re: Attribute packed and alignment

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

 





On 18/04/2021 15:10, Matwey V. Kornilov via Gcc-help wrote:

Hi,

When a structure is declared as `__attribute__ ((packed))' what should
it alignment be? Unfortunately, I have not found clear statement in the
docs, but I've found the following very inconsistent behavior instead.
It is not clear to me to what extent `__attribute__ ((packed))' should
break alignment rules.


Imagine the following code:

typedef struct {
	unsigned char a;
	unsigned char b;
	unsigned short c;
	unsigned int d;
	unsigned long e;
} __attribute__ ((packed)) s;

s x = {
	.a = 1,
	.b = 2,
	.c = 3,
	.d = 4,
	.e = 5
};


Creating a static instance of an object and examining its actual alignment doesn't tell you anything concrete, as you've found. A compiler is free to over-align an instance of an object if it might lead to better code generation later on.

A better test would be a case such as

typedef struct {
	unsigned char a;
	unsigned char b;
	unsigned short c;
	unsigned int d;
	unsigned long e;
} __attribute__ ((packed)) s;

struct t
{
   long long x;  // Force 64-bit alignment
   char y;       // One byte into next double-word
s z; // Amount of padding before this will show alignment needed.
};

unsigned u = __builtin_offsetof (t, z);

You should find this stable across all optimization levels. On aarch64 you'll get the answer 9, showing that the object has just byte alignment (no padding needed).

R.


I compile it in the following four different ways:

A. aarch64-suse-linux-gcc-7 -c -fdata-sections -o test.o test.c
B. aarch64-suse-linux-gcc-7 -c -Os -fdata-sections -o test.o test.c
C. aarch64-suse-linux-gcc-11 -c -fdata-sections -o test.o test.c
D. aarch64-suse-linux-gcc-11 -c -Os -fdata-sections -o test.o test.c

gcc versions are the following:

aarch64-suse-linux-gcc-7 (SUSE Linux) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

aarch64-suse-linux-gcc-11 (SUSE Linux) 11.0.1 20210416 (experimental)
[revision 49813aad3292f7f2bef69206274da78a9a7116ed]
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Then, using `objdump -x test.o', I examine `.data.x` section Alignment:

A.   3 .data.x       00000010  0000000000000000  0000000000000000
00000040  2**3

B.   3 .data.x       00000010  0000000000000000  0000000000000000
00000040  2**3

C.   3 .data.x       00000010  0000000000000000  0000000000000000
00000040  2**3

D.   3 .data.x       00000010  0000000000000000  0000000000000000
00000040  2**0


Note, that -Os on gcc 11 forces the Aligment to 1 byte. I've found this
when tried to build some vendor tree of u-boot bootloader. Bumping
version from gcc 7 to gcc 11 breaks the firmware image.




[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