Is it able to define a variable length struct in gnuc to represent a object as follow:
field1: fixed 4bytes;
field2: length of field3
field3: variable length
field4: length of field5
field5: variable length
field6: fixed 8bytes
field7: fixed 1byte
I know in gnuc we can use the zero-size array to implement a variable length struct, e.g.
typedef struct varStruct{
int foo1;
int foo2[0];
}varStruct;
But the above usage requires the variable length field placed at the tail of the struct.
What if they are in the middle?
You can't have a struct with more than one variable array or a variable array in the middle. Think about it, how would the compiler know where field3
and field4
start if the length field2
is variable?
If field1
contains the length of the next two fields, you could read the members of the struct manually. Example code (read it as pseudocode):
#define PADDING 8 /* or perhaps sizeof(void *) */
typedef struct {
int32_t field_len;
char data[0];
} main_str_t;
typedef struct {
int64_t one;
int8_t another;
} tail_str_t;
....
main_str_t *data = get_data();
int32_t len = data->field_len;
int32_t padded_len = ((field_len + PADDING - 1) / PADDING) * PADDING;
char *field2 = data->data;
char *field3 = field2 + padded_len;
tail_str_t *tail = field3 + padded_len;
Not possible, since the compiler (is responsible for and) will not be able to calculate offsets for field4
and field5
.
You'll need to do this with 3 structs and do a little address arithmetic at run-time:
struct1:
field1: fixed 4bytes;
field2: length of field3
field3: variable length
struct2:
field4: length of field5
field5: variable length
struct3:
field6: fixed 8bytes
field7: fixed 1byte