This is about http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38736 and I'd rather
discuss it in gcc mail list. Basicly the problem is shown as following example:
Case 1 (on x86 or x86_64):
$ cat i.h
struct s
{
char dummy0;
// align at maxmiun aligned boundary supported by this target.
char dummy __attribute__((aligned));
int data;
};
extern void foo(struct s*);
$ cat foo.c
#include "i.h"
void foo(struct s* input)
{ input->data = 1; }
$ cat main.c
#include "i.h"
extern void abort(void);
struct s g_s;
int main()
{
foo(&g_s);
if (g_s.data != 1) abort();
}
$ gcc -S foo.c
$ gcc -S main.c -mavx
$ gcc -o foo.exe foo.s main.s
$ ./foo.exe
Aborted
The reason is that AVX target defines BIGGEST_ALIGNMENT to 32 bytes and non-AVX
x86 target does as 16 bytes. Since __attribute__((aligned)) aligns struct
memory according to BIGGEST_ALIGNMENT, objects built by avx/non-avx GCC will
result in different struct layout.
There are options to solve this problem so far I can think of:
Option 1: Leave BIGGEST_ALIGNMENT as it is nowaday and modify all libraries and
header files using __attribute__((aligned)) similar to i.h
Option 2: Define BIGGEST_ALIGNMENT as a fixed value 16 bytes, for all x86
target.
Option 3: Define BIGGEST_ALIGNMENT as a fixed value 32 bytes, for all x86
target, and extend to 64 or more bytes in future.
Option 1 follows the definition of __attribute__((aligned)) in GCC manual, and
it works as expected to provide a way to align at maxium target alignment.
However, fixing all libraries will be tidious and easy to miss. Also
documentation should mention the potiential issue using this feature.
Option 2 and option 3 seems to be a quick solution, but their draw back is
obvious. Firstly it doesn't follow the definition of __attribute__((aligned))
and can leave confusion to users. Secondly it eliminates a convenient way for
user utilize the maxium alignment supported in x86 family. Also very
importantly they won't solve all problem, for example if i.h is like this:
Case 2:
$ cat i2.h
#ifdef __AVX__
#define aligned __aligned__(32)
#else
#define aligned __aligned__(16)
#endif
struct s
{
char dummy0;
char dummy __attribute__((aligned));
int data;
};
extern void foo(struct s*);
Furthermore option 3 will result different behavior for GCC 4.3- and GCC 4.4+,
case 1 will still fail if foo.c is built by GCC 4.3- and main.c by 4.4+.
In summary, I don't see an obvious best way to solve in PR38736. But IMHO
option 1 is more reasonable.
Thanks - Joey