It seems that top level objects in gcc targeting x86 that are >= 32 bytes automatically get 32 byte alignment. This may be nice for performance, but I'm collecting an array of thingies from all my object files in a user-defined section, and the extra alignment gaps play havoc with this array. Is there any way to prevent this object alignment?
To clarify, I have a low-aligned struct, and different object files define data in the form of an array of that struct in a user defined section, with the purpose to make one application wide array. As soon as one of those arrays is >= 32, the object alignment and with that the section alignment is pushed to 32 and when the linker concatenates the separate sections from the object files into the executable, it creates alignment fillers at the module boundaries in that section.
The following program illustrates a possible solution, assuming GCC extensions are acceptable to you:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define ALIGNMENT // __attribute__ ((aligned (8)))
struct A {
char arr[40];
} ;
struct A a __attribute__ ((section ("my_data"))) ALIGNMENT = {{'a'}};
struct A b __attribute__ ((section ("my_data"))) ALIGNMENT = {{'b'}};
struct A c __attribute__ ((section ("my_data"))) ALIGNMENT = {{'c'}};
int main(int argc, char **argv)
{
assert(sizeof(struct A) == 40);
printf("%c\n",a.arr[0]);
printf("%c\n",b.arr[0]);
printf("%c\n",c.arr[0]);
printf("%lu\n",(unsigned long)(&a));
printf("%lu\n",(unsigned long)(&b));
printf("%lu\n",(unsigned long)(&c));
return 0;
}
My output is:
a
b
c
6295616
6295680
6295744
Note that in my (64-bit) executable each of the three 40-byte structures is 64-byte aligned.
Now uncomment // __attribute__ ((aligned (8)))
, rebuild and rerun. My
output then is:
a
b
c
6295616
6295656
6295696
Now the structures are 8-byte aligned, without gaps.