Memory alignment of arrays
The alignment attribute specifies the alignment of variables or structure fields, not single array elements. See Specifying Attributes of Variables and Common Variable Attributes for details.
If you always want to align two integers together, you can define a structure
struct dma_transfer {
unsigned int e0 __attribute__ ((aligned (16)));
unsigned int e1 __attribute__ ((aligned (16)));
};
This aligns the elements on 16 byte boundaries.
int main(int argc, char **argv)
{
static struct dma_transfer a;
static unsigned int b[2];
printf("a.e0 = %p\n", &a.e0);
printf("a.e1 = %p\n", &a.e1);
printf("b[0] = %p\n", &b[0]);
printf("b[1] = %p\n", &b[1]);
return 0;
}
gives, e.g.
a.e0 = 0x601060
a.e1 = 0x601070
b[0] = 0x601080
b[1] = 0x601084
But this means also, that you have holes between the two integer values. On a 32 bit system, you will have
| int 4 bytes | hole 12 bytes |
| int 4 bytes | hole 12 bytes |
If arr
is an array of 32-bit elements, and the address of arr[0]
is 0xXXXXXXX0
, then the address of arr[1]
will necessarily be 0xXXXXXXX4
.
For your purpose, you need to use arrays of 16-byte elements:
typedef struct
{
unsigned int x;
unsigned char reserved[16-sizeof(unsigned int)];
}
element_t;
static element_t a[2] __attribute__ ((aligned (16)));
static element_t b[2] __attribute__ ((aligned (16)));
static element_t c[2] __attribute__ ((aligned (16)));
static element_t d[2] __attribute__ ((aligned (16)));
Alternatively, you can simply refrain from using arrays altogether.
Instead, use plain variables, and tell the compiler to align them to 16 bytes:
static unsigned int a0 __attribute__ ((aligned (16)));
static unsigned int a1 __attribute__ ((aligned (16)));
static unsigned int b0 __attribute__ ((aligned (16)));
static unsigned int b1 __attribute__ ((aligned (16)));
static unsigned int c0 __attribute__ ((aligned (16)));
static unsigned int c1 __attribute__ ((aligned (16)));
static unsigned int d0 __attribute__ ((aligned (16)));
static unsigned int d1 __attribute__ ((aligned (16)));
I really don't think you can do that ... You're trying to get the compiler to inject extra padding for alighment purposes "inside" an unsigned int
. But there's no space to do that, all of the bits in an unsigned int
are already used for the integer itself.
I think the solution is to wrap the integer in a structure, since then you can use the __attribute__(())
magic on the structure, and make an array of that.