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