Defererencing a pointer
to a struct
with a Flexible Array Member (FAM) doesn't "copy" the FAM?
That seems to be the behavior, according to this program, which creates as instance of a struct with an FAM and then inspects the "binary layout" of both a pointer to the struct and a dereference of the struct.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
typedef struct{
uint8_t idim;
uint32_t data[];
}array_t; // https://gustedt.wordpress.com/2011/03/14/flexible-array-member/
int64_t x_bdim = sizeof(array_t) + sizeof(uint32_t)*0x2;
array_t* _x = aligned_alloc(0x1000,x_bdim);
array_t x = *_x;
uint8_t* raw;
x.idim = 0xff;
x.data[0x0] = 0x11111111;
x.data[0x1] = 0x22222222;
_x->idim = 0xff;
_x->data[0x0] = 0x11111111;
_x->data[0x1] = 0x22222222;
printf("%'ld %'ld %'ld\n", sizeof(array_t), sizeof(array_t) + sizeof(uint32_t)*0x2, x_bdim);
putchar(0x0a);
raw = (uint8_t*)_x;
for(int i=0; i<x_bdim; ++i)
printf("%02x\n", raw[i]);
putchar(0x0a);
for(int i=0; i<0x2; ++i)
printf("%08x\n", _x->data[i]);
putchar(0x0a);
raw = (uint8_t*)&x;
for(int i=0; i<x_bdim; ++i)
printf("%02x\n", raw[i]);
putchar(0x0a);
for(int i=0; i<0x2; ++i)
printf("%08x\n", x.data[i]);
}
Am I missing something, or is this correct? Is the morale of the story that we shouldn't deference (pointers to) structs with a Flexible Array Member, because we only get the "header" of the struct and not the full array data?
That would be correct. The compiler does not know the size of the array and assumes 0 for such operations, including copy, return, assign, and compare. In effect, the flexible array is after the struct.
GCC's prototype syntax was more obvious. They had it written as uint32_t data[0];