Where attribute((aligned)) is allowed to decrease alignment
Andrew C Aitchison
andrew@aitchison.me.uk
Fri Jun 13 21:37:13 GMT 2025
On Fri, 13 Jun 2025, Tom V wrote:
> Hi Segher,
>
> On Fri, 13 Jun 2025 13:37 Segher Boessenkool wrote:
>> On Fri, Jun 13, 2025 at 06:52:19PM +0100, Tom V wrote:
>
>> As the documentation says:
>> When used on a struct, or struct member, the 'aligned' attribute
>> can only increase the alignment; in order to decrease it, the
>> 'packed' attribute must be specified as well. When used as part
>> of a typedef, the 'aligned' attribute can both increase and decrease
>> alignment, and specifying the 'packed' attribute generates a
>> warning.
>
> The documentation is clear for struct members. I am not asking about
> that (although it is tangentially related).
>
> Suppose I declare:
>
> typedef int a_type;
> typedef int __attribute__((aligned(1))) b_type;
> typedef int __attribute__((aligned(32))) c_type;
>
> a_type * a;
> b_type * b;
> c_type * c;
>
> a is a pointer to a normally aligned int.
> b is a pointer to a possibly unaligned int.
> c is a pointer to a "super-aligned" int.
>
> Any time the compiler generates a read or write access to *b it
> correctly generates only instructions that work at non-aligned
> addresses. On a platform where being more aligned than normal was
> helpful, I expect it would also be able to generate instructions to
> make use of that feature when accessing *c.
>
> However, if I declare the exact same thing in one go without a typedef,
> it doesn't work:
>
> int * a;
> int __attribute__((aligned(1))) * b;
> int __attribute__((aligned(32))) * c;
Does
int * a;
int * __attribute__((aligned(1))) b;
int * __attribute__((aligned(32))) c;
behave the same ?
I ask since
int const * a;
and
int * const a;
are different.
Of course
a possibly unaligned pointer to an int
(if that is that you get) may not be what you want.
> The attribute on the pointed-to type can only increase alignment, much
> like a struct member, however because this is not inside a struct,
> adding attribute((packed)) causes an error, so the alignment cannot be
> decreased.
>
> When these are function arguments, the behaviour is different again:
>
> void foo(int * a);
> void bar(int __attribute__((aligned(1))) * b);
> void baz(int __attribute__((aligned(32))) * c);
>
> The declarations with the aligned attribute here cause an error. This
> seems to be a bug. Obviously a function argument has to be at an exact
> specific location (register or stack) but it seems like the checking
> code that is disallowing the aligned attribute on the argument is
> incorrectly disallowing it on the pointed-to type.
>
> Unless someone knows different?
>
>
> Thanks,
> Tom
>
--
Andrew C. Aitchison Kendal, UK
andrew@aitchison.me.uk
More information about the Gcc-help
mailing list