public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* An odd case with structure field alignment.
@ 2022-09-04 13:32 Iain Sandoe
  2022-09-05  8:53 ` Richard Biener
  0 siblings, 1 reply; 3+ messages in thread
From: Iain Sandoe @ 2022-09-04 13:32 UTC (permalink / raw)
  To: GCC Development

Hi,

I am clearly missing something here … can someone point out where it is?

https://gcc.gnu.org/onlinedocs/gcc-3.3/gcc/Variable-Attributes.html#Variable%20Attributes
in the discussion of applying this to structure fields:

"The aligned attribute can only increase the alignment; but you can decrease it by specifying packed as well."

Consider:

struct odd {
  int * __attribute__((aligned(2))) a;
  char c;
};

I would expect, given reading of the information on the aligned attribute, that the under-alignment of a would be ignored (since there is no packed attribute on either the field or the struct).

However, on x86_64, powerpc64 linux and x86_64, powerpc Darwin, I see that the size of the struct is sizeof(pointer) + 2 and the alignment is 2.

OTOH:

struct OK {
  int  __attribute__((aligned(2))) a;
  char c;
};

behaves as expected (the under-alignment is ignored, silently).

as does this…

struct maybe {
  int *a  __attribute__((aligned(2)));
  char c;
};

* the type of the pointer does not seem to be relevant (i.e. AFAICT the behaviour is the same for char * etc.)

Is there some special rule about pointers that I have not found ?

[it’s making an ABI mismatch with clang, which treats the int * as expected from the documentation quoted above]

cheers
Iain




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: An odd case with structure field alignment.
  2022-09-04 13:32 An odd case with structure field alignment Iain Sandoe
@ 2022-09-05  8:53 ` Richard Biener
  2022-09-05  9:06   ` Iain Sandoe
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Biener @ 2022-09-05  8:53 UTC (permalink / raw)
  To: Iain Sandoe; +Cc: GCC Development

On Sun, Sep 4, 2022 at 3:33 PM Iain Sandoe <iain@sandoe.co.uk> wrote:
>
> Hi,
>
> I am clearly missing something here … can someone point out where it is?
>
> https://gcc.gnu.org/onlinedocs/gcc-3.3/gcc/Variable-Attributes.html#Variable%20Attributes
> in the discussion of applying this to structure fields:
>
> "The aligned attribute can only increase the alignment; but you can decrease it by specifying packed as well."
>
> Consider:
>
> struct odd {
>   int * __attribute__((aligned(2))) a;

I think this applies the attribute to the type.  For non-aggregate
types 'packed' is ignored.  So the above
is equivalent to

typedef int *A __attribute__((aligned(2)));

struct odd {
  A a;
  char c;
};

>   char c;
> };
>
> I would expect, given reading of the information on the aligned attribute, that the under-alignment of a would be ignored (since there is no packed attribute on either the field or the struct).
>
> However, on x86_64, powerpc64 linux and x86_64, powerpc Darwin, I see that the size of the struct is sizeof(pointer) + 2 and the alignment is 2.
>
> OTOH:
>
> struct OK {
>   int  __attribute__((aligned(2))) a;
>   char c;
> };
>
> behaves as expected (the under-alignment is ignored, silently).
>
> as does this…
>
> struct maybe {
>   int *a  __attribute__((aligned(2)));
>   char c;
> };

Where for both of these cases the attribute applies to the FIELD_DECL.
The documentation refers to
alignment of fields, not the alignment of types.

At least that's my understanding of this issue.

IIRC clang has issues when matching GCC attribute parsing rules, esp.
when applied to pointer types.

Richard.

> * the type of the pointer does not seem to be relevant (i.e. AFAICT the behaviour is the same for char * etc.)
>
> Is there some special rule about pointers that I have not found ?
>
> [it’s making an ABI mismatch with clang, which treats the int * as expected from the documentation quoted above]
>
> cheers
> Iain
>
>
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: An odd case with structure field alignment.
  2022-09-05  8:53 ` Richard Biener
@ 2022-09-05  9:06   ` Iain Sandoe
  0 siblings, 0 replies; 3+ messages in thread
From: Iain Sandoe @ 2022-09-05  9:06 UTC (permalink / raw)
  To: Richard Biener; +Cc: GCC Development



> On 5 Sep 2022, at 09:53, Richard Biener via Gcc <gcc@gcc.gnu.org> wrote:
> 
> On Sun, Sep 4, 2022 at 3:33 PM Iain Sandoe <iain@sandoe.co.uk> wrote:
>> 
>> Hi,
>> 
>> I am clearly missing something here … can someone point out where it is?
>> 
>> https://gcc.gnu.org/onlinedocs/gcc-3.3/gcc/Variable-Attributes.html#Variable%20Attributes
>> in the discussion of applying this to structure fields:
>> 
>> "The aligned attribute can only increase the alignment; but you can decrease it by specifying packed as well."
>> 
>> Consider:
>> 
>> struct odd {
>>  int * __attribute__((aligned(2))) a;
> 
> I think this applies the attribute to the type.  

That was what I wondered - but it does not seem to apply the under-alignment to a non-pointer type ...

> For non-aggregate
> types 'packed' is ignored.  So the above
> is equivalent to
> 
> typedef int *A __attribute__((aligned(2)));
> 
> struct odd {
>  A a;
>  char c;
> };

Which (for the record) works as expected on both compilers.
> 
>>  char c;
>> };
>> 
>> I would expect, given reading of the information on the aligned attribute, that the under-alignment of a would be ignored (since there is no packed attribute on either the field or the struct).
>> 
>> However, on x86_64, powerpc64 linux and x86_64, powerpc Darwin, I see that the size of the struct is sizeof(pointer) + 2 and the alignment is 2.
>> 
>> OTOH:
>> 
>> struct OK {
>>  int  __attribute__((aligned(2))) a;
>>  char c;
>> };

However, this does _not_ treat the same sequence as “typedef int A __attribute__((aligned(2)))”

>> behaves as expected (the under-alignment is ignored, silently).
>> 
>> as does this…
>> 
>> struct maybe {
>>  int *a  __attribute__((aligned(2)));
>>  char c;
>> };
> 
> Where for both of these cases the attribute applies to the FIELD_DECL.

> The documentation refers to
> alignment of fields, not the alignment of types.

sure, but I can’t at the moment see a consistent rule to file a bug about.

> At least that's my understanding of this issue.
> 
> IIRC clang has issues when matching GCC attribute parsing rules, esp.
> when applied to pointer types.

probably; when I looked at the decls produced there seemed to be no way to
to tell the position of the attribute in the decl (so to decide if it’s a type attr or a
field attr). … possibly that means poking at the parser too… 

attributes in aggregates are fun, for sure ..  

Iain

> 
> Richard.
> 
>> * the type of the pointer does not seem to be relevant (i.e. AFAICT the behaviour is the same for char * etc.)
>> 
>> Is there some special rule about pointers that I have not found ?
>> 
>> [it’s making an ABI mismatch with clang, which treats the int * as expected from the documentation quoted above]
>> 
>> cheers
>> Iain


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-09-05  9:06 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-04 13:32 An odd case with structure field alignment Iain Sandoe
2022-09-05  8:53 ` Richard Biener
2022-09-05  9:06   ` Iain Sandoe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).