i have the following code:
#include <stdio.h>
int
main(void)
{
float a[4] __attribute__((aligned(0x1000))) = {1.0, 2.0, 3.0, 4.0};
printf("%p %p %p %p\n", &a[0], &a[1], &a[2], &a[3]);
}
And i have the following output:
0x7fffbfcd2da0 0x7fffbfcd2da4 0x7fffbfcd2da8 0x7fffbfcd2dac
Why the address of a[0]
is not a multiple of 0x1000
?
What exactly __attribute__((aligned(x)))
does? I misunderstood this explanation?
I'm using gcc 4.1.2.
There was a bug in gcc that caused attribute aligned to not work with stack variables. It appears to be fixed with the patch linked below. The link below also contains quite a bit of discussion for the problem as well.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16660
I have tried your code above with two different versions of gcc: 4.1.2 from a RedHat 5.7 box, and it failed similarly to your problem (the local arrays wre in no way aligned on 0x1000 byte boundaies). I then tried your code with gcc 4.4.6 on RedHat 6.3, and it worked flawlessly (the local arrays were aligned). The Myth TV folks had a similar problem (that the gcc patch above seemed to fix):
http://code.mythtv.org/trac/ticket/6535
Anyway, it looks like you found a bug in gcc, that appears to be fixed in later versions.
Alignement is not effective for all types. You should consider using a structure to see the attributes in action:
And then, you'll read:
Which is what you were expecting.
Edit: Pushed by @yzap and following @Caleb Case comment, the initial problem is due to GCC version only. I've checked on GCC 3.4.6 vs GCC 4.4.1 with the requester's source code:
It's now obvious that older GCC versions (somewhere before 4.4.1) shows alignment pathologies.
Note 1: My proposed code doesn't answer the question which I understood as "aligning each field of the array".
Note 2: Bringing non-static a[] inside main() and compiling with GCC 3.4.6 breaks the alignment directive of the array of struct but keeps 0x1000 distance between structs... still bad ! (see @zifre answer for workarounds)
I believe the problem is that your array is on the stack. Because the stack pointer could be anything when the function starts, there is no way to align the array without allocating a lot more than you need and adjusting it. If you move the array out of the function and into a global variable, it should work. The other thing you could do is keep it as a local variable (which is a very good thing), but make it
static
. This will prevent it from being stored on the stack. Beware that both of these ways are not thread-safe or recursion-safe, since there will be only one copy of the array.With this code:
I get this:
which is what is expected. With your original code, I just get random values like you did.
Recent GCC (tested with 4.5.2-8ubuntu4) appear to work as expected with the array aligned properly.
I get: