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.