I am trying to align compound literal to 16 bytes.
I found this
which is :
#define ALIGNED_STRING(S) (struct { _Alignas(16) char s[sizeof S]; }){ S }.s
char *u = ALIGNED_STRING("agsdas");
which compiles.
and tried to apply it to uint32_t.
I tried this so far with gcc.
#define BLOCK_ALIGNED_U32(...) (struct { _Alignas(16) uint32_t x[sizeof ((uint32_t[]){__VA_ARGS__})]; }){ __VA_ARGS__ }.x
uint32_t toto[] = BLOCK_ALIGNED_U32(0x11111111, 0x22222222);
and even:
uint32_t tata[] = (struct { uint32_t __attribute__((aligned(16))) x[2]; }){.x = {0x11111111, 0x22222222}}.x;
but it gives me error : invalid initializer
What am I doing wrong / missing?
note: I am doing this because I want to control the aligment of some data block inside a structure declaration, like this:
struct
{
uint32_t* foo1;
uint32_t* foo2;
uint32_t* foo3;
uint32_t* foo4;
}s_t;
s_t foo[]=
{
.foo1 = BLOCK_ALIGNED_U32(1,2,3),
.foo2 = BLOCK_ALIGNED_U32(2,2),
.foo3 = (uint32_t[]){1,2,3},//could be not 16-bytes-aligned
.foo4 = (uint32_t[]){2,2},//could be not 16-bytes-aligned
}
At least these issues:
OP's macro array sizing was wrong.
// uint32_t x[sizeof ((uint32_t[]){__VA_ARGS__})]
uint32_t x[sizeof ((uint32_t[]){__VA_ARGS__}) / sizeof(uint32_t)]
Add { }
// OP's
#define ALIGNED_U32(...) (struct { _Alignas(16) uint32_t x[sizeof ((uint32_t[]){ __VA_ARGS__}) ]; }){ __VA_ARGS__ }.x
// Suggested fix
#define ALIGNED_U32(...) (struct { _Alignas(16) uint32_t x[sizeof ((uint32_t[]){ __VA_ARGS__})/sizeof(uint32_t)]; }){ { __VA_ARGS__ } }.x
Sample usage
#define ALIGNED_U32(...) (struct { _Alignas(16) uint32_t x[ \
sizeof ((uint32_t[]){ __VA_ARGS__ })/sizeof(uint32_t) \
]; }) { .x = { __VA_ARGS__ } }.x
typedef struct {
uint32_t *foo1;
uint32_t *foo2;
uint32_t *foo3;
uint32_t *foo4;
} s_t;
s_t foo = { //
.foo1 = ALIGNED_U32(1, 2, 3), //
.foo2 = ALIGNED_U32(2, 2), //
.foo3 = (uint32_t[]) {1, 2, 3}, // might be not 16-bytes-aligned
.foo4 = (uint32_t[]) {2, 2}, // might be not 16-bytes-aligned
};