[Bug c/94338] struct member alignment is not carried over to alignment of struct variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338 --- Comment #11 from huaixin chang --- (In reply to huaixin chang from comment #10) > (In reply to Richard Biener from comment #9) > > Btw, > > > > struct X { > > long a __attribute__((__aligned__(128))); > > long b __attribute__((__aligned__(128))); > > }; > > struct X A __attribute__((__aligned__(4))); > > > > is not diagnosed (this is what your testcase is, decomposed). > > > > I can't reproduce the diagnostics you describe in comment#5 > > I am sorry that I made a mistake in testing typedef described in comment#5. > > I spelled __aligned__ into __aligned, got warned "warning: '__aligned' > attribute directive ignored [-Wattributes]", and thought I got diagnosed > because of reduction in alignment. As a result, neither type foo nor object > A is reduced in alignment with the code describe in comment#5. > > I have tested typedef again, and found that it behaves the same with using > struct under gcc 9.2.1. That is to say, no matter I define A using struct > like: > > --- > struct X { > long a __attribute__((__aligned__(128))); > long b __attribute__((__aligned__(128))); > }; > struct X A __attribute__((__aligned__(4))); > > or use typedef and reduce the alignment of type foo like: > --- > typedef struct { > long a __attribute__((__aligned__(128))); > long b __attribute__((__aligned__(128))); > } foo __attribute__((__aligned(4))); Another spelling mistake. It should be: } foo __attribute__((__aligned__(4))); > > foo A; > > or use typedef and reduce the alignment of A like: > --- > typedef struct { > long a __attribute__((__aligned__(128))); > long b __attribute__((__aligned__(128))); > } foo; > > foo A __attribute__((__aligned__(4))); > > I got no warn on compiling and it behaves like this. > --- > address of A 0x42003c > alignof A 4 > address of A.a 0x42003c > alignof A.a 128 > address of A.b 0x4200bc > alignof A.b 128 > address of B 0x420038
[Bug c/94338] struct member alignment is not carried over to alignment of struct variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338 --- Comment #10 from huaixin chang --- (In reply to Richard Biener from comment #9) > Btw, > > struct X { > long a __attribute__((__aligned__(128))); > long b __attribute__((__aligned__(128))); > }; > struct X A __attribute__((__aligned__(4))); > > is not diagnosed (this is what your testcase is, decomposed). > > I can't reproduce the diagnostics you describe in comment#5 I am sorry that I made a mistake in testing typedef described in comment#5. I spelled __aligned__ into __aligned, got warned "warning: '__aligned' attribute directive ignored [-Wattributes]", and thought I got diagnosed because of reduction in alignment. As a result, neither type foo nor object A is reduced in alignment with the code describe in comment#5. I have tested typedef again, and found that it behaves the same with using struct under gcc 9.2.1. That is to say, no matter I define A using struct like: --- struct X { long a __attribute__((__aligned__(128))); long b __attribute__((__aligned__(128))); }; struct X A __attribute__((__aligned__(4))); or use typedef and reduce the alignment of type foo like: --- typedef struct { long a __attribute__((__aligned__(128))); long b __attribute__((__aligned__(128))); } foo __attribute__((__aligned(4))); foo A; or use typedef and reduce the alignment of A like: --- typedef struct { long a __attribute__((__aligned__(128))); long b __attribute__((__aligned__(128))); } foo; foo A __attribute__((__aligned__(4))); I got no warn on compiling and it behaves like this. --- address of A 0x42003c alignof A 4 address of A.a 0x42003c alignof A.a 128 address of A.b 0x4200bc alignof A.b 128 address of B 0x420038
[Bug c/94338] struct member alignment is not carried over to alignment of struct variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338 --- Comment #7 from huaixin chang --- (In reply to Martin Sebor from comment #4) > Sounds like there's agreement that the code should at least get a warning > then, so confirmed. > > The attribute aligned section of the manual describing the variable > attribute says: > > When used on a struct, or struct member, the aligned attribute can only > increase the alignment... > > It's not clear whether struct here refers to a type or a variable (I'm > guessing it's former but it's in the Common Variable Attribute section so it > could easily be read as the latter). Either way, reducing the alignment of > an object whose members explicitly ask for stricter alignment seems like a > dangerous thing to do without a warning. > > I'll see if I can do this for GCC 11. It seems that the compiler thinks A.a is already aligned to 128-byte. Because as I print alignof(A.a) and alignof(A.b) with the same definition, they are 128. $./align address of A 0x42003c alignof A 4 address of A.a 0x42003c alignof A.a 128 address of A.b 0x4200bc alignof A.b 128 Is it in your consideration to actually align A.a to 128-byte boundary?
[Bug c/94338] struct member alignment is not carried over to alignment of struct variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338 --- Comment #6 from huaixin chang --- (In reply to jos...@codesourcery.com from comment #3) > It's a mistake to be referring to the C standard for the interpretation of > alignment attributes. The C standard way of specifying alignment is > _Alignas, not __attribute__, and if you write equivalent code using > _Alignas you get an error "error: '_Alignas' specifiers cannot reduce > alignment of 'A'", which corresponds to the constraint "The combined > effect of all alignment specifiers in a declaration shall not specify an > alignment that is less strict than the alignment that would otherwise be > required for the type of the object or member being declared.". Yes, I tested with _Alignas and got that error.
[Bug c/94338] struct member alignment is not carried over to alignment of struct variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338 --- Comment #5 from huaixin chang --- (In reply to Richard Biener from comment #2) > I think the testcase is ill-formed and should be diagnosed in some form. > IIRC there's some documented behavior (that's not implemented) that > __aligned__ > only increases alignment unless __packed__ is used. With __packed__ the > testcase behaves as expected I think. > > Note __attribute__((__aligned__(4))) applies to 'A', not its type. Yes, I missed this and quoted wrong document for this case. > > Not sure if behavior changes if you use a typedef that is aligned to 4. If a use a typedef that is aligned to 4 like this: typedef struct { long a __attribute__((__aligned__(128))); long b __attribute__((__aligned__(128))); } foo __attribute__((__aligned(4))); foo A; Or align variable A to 4 only like this: typedef struct { long a __attribute__((__aligned__(128))); long b __attribute__((__aligned__(128))); } foo; foo A __attribute__((__aligned(4))); I will get warned while compiling and alignment is as expected.
[Bug c/94338] struct member alignment is not carried over to alignment of struct variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338 --- Comment #1 from huaixin chang --- I have tested on x86_64 with gcc version 4.8.5 20150623, and also arm with gcc version 9.2.1 20190812. They behaves the same.
[Bug c/94338] New: struct member alignment is not carried over to alignment of struct variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94338 Bug ID: 94338 Summary: struct member alignment is not carried over to alignment of struct variable Product: gcc Version: lto Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: huaixin@alibaba-inc.com Target Milestone: --- Document says that “alignment of any given struct or union type is required by the ISO C standard to be at least a perfect multiple of the lowest common multiple of the alignments of all of the members of the struct or union in question.” When the alignment requirement of struct variable is smaller than the alignment requirement of its member variable, the compiler's behavior is not specified. Here is the code. #include struct { long a __attribute__((__aligned__(128))); long b __attribute__((__aligned__(128))); } A __attribute__((__aligned__(4))); struct { int a; } B; int main() { printf("address of A %lx\n", ); printf("address of A.a %lx\n", ); printf("address of A.b %lx\n", ); printf("address of B %lx\n", ); printf("address of B.a %lx\n", ); return 0; } And it goes like this. $gcc align.c -o align $./align address of A 42003c address of A.a 42003c address of A.b 4200bc address of B 420038 address of B.a 420038 Member a and b of struct variable A are not aligned to 128-byte boundary. I wonder if it is the users' responsible not to write like this. Or is it the compiler's responsible to align A.a and A.b to 128-byte boundary?