Re: Where attribute((aligned)) is allowed to decrease alignment

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

 



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;

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



[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