views:

3143

answers:

1

Hi,

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.

Thanks in advance.

+15  A: 

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:

#include <stdio.h>

float a[4] __attribute__((aligned(0x1000))) = {1.0, 2.0, 3.0, 4.0};

int
main(void)
{
        printf("%p %p %p %p\n", &a[0], &a[1], &a[2], &a[3]);
}

I get this:

0x804c000 0x804c004 0x804c008 0x804c00c

which is what is expected. With your original code, I just get random values like you did.

Zifre
+1 correct answer. An alternate solution is to make the local array static. Alignment on the stack is always a problem and it's best to get into the habit of avoiding it.
Dan Olson
Oh yes, I didn't think of making it static. That is a good idea since it prevents name collisions. I will edit my answer.
Zifre