1

You can't have arrays of structures with flexible array members.

This is the TL;DR of this question. And thinking about it, it makes perfect sense.

However, may one simulate an array of structures with flexible array member - let's call them swfam - of fixed size as below :

#include <assert.h>
#include <stdlib.h>


typedef struct {
    int foo;
    float bar[];
} swfam_t; // struct with FAM

typedef struct { // this one also has a FAM but we could have used a char array instead
    size_t size,  // element count in substruct
           count; // element count in this struct
    char data[];
} swfam_array_t;


#define sizeof_swfam(size) (sizeof(swfam_t) + (size_t)(size) * sizeof(float))


swfam_array_t *swfam_array_alloc(size_t size, size_t count) {
    swfam_array_t *a = malloc(sizeof(swfam_array_t) + count * sizeof_swfam(size));

    if (a) {
        a->size = size;
        a->count = count;
    }

    return a;
}

size_t swfam_array_index(swfam_array_t *a, size_t index) {
    assert(index < a->count && "index out of bounds");
    return index * sizeof_swfam(a->size);
}

swfam_t *swfam_array_at(swfam_array_t *a, size_t index) {
    return (swfam_t *)&a->data[swfam_array_index(a, index)];
}


int main(int argc, char *argv[]) {
    swfam_array_t *a = swfam_array_alloc(100, 1000);
    assert(a && "allocation failed");

    swfam_t *s = swfam_array_at(a, 42);

    s->foo = -18; // do random stuff..
    for (int i = 0; i < 1000; ++i)
        s->bar[i] = (i * 3.141592f) / s->foo;

    free(a);
    return 0;
}

Is the trick valid C99 / C11 ? Am I lurking towards undefined behaviour ?

1 Answer 1

0

One way to do this would be to use a pointer member instead of a flexible array. You would then have to manually allocate its size via malloc() et. al. [] is typically used only when the array is initialized on declaration, which is not possible with struct, which is essentially a definition, not a declaration. The ability to immediately declare an instance of the struct type does not change the nature of the definition, it's just for convenience.

typedef struct {
    int foo;
    float* bar; } swfam_t; // struct with FAM
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.