cgccalignmentcompound-literals

How to get a specific aligment for compound literals?


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
}

Solution

  • At least these issues:

    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
    };