On 19/04/2021 15:36, Xi Ruoyao via Gcc-help wrote:
On Mon, 2021-04-19 at 12:05 +0100, Richard Earnshaw via Gcc-help wrote:
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
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).
Would C99 _Alignof operator work for this? Like:
printf("%d\n", _Alignof(s));
Yes, but alignof is implemented in essentially the same way as I've just
described. Actually, you don't need the initial long long in my struct,
then the result is identical to _Alignof().
R.