Search code examples
cstructc99flexible-array-member

Is it legal to create a flexible array member of size zero?


The C99 standard allows the creation of flexible array members such as

typedef struct pstring {
  size_t length;
  char   string[];
} pstring;

This is then initialized with something like pstring* s = malloc(sizeof(pstring) + len). Is it permissible for len to be zero? It would seem consistent, and would be nice for saving space from time to time (probably not with the pstring example, of course). On the other hand, I have no idea what the following code would do:

pstring* s = malloc(sizeof(pstring));
s->string;

This also seems like the sort of thing which might work with one compiler and not another, or on one OS and not another, or on one day and not another, so what I really want to know is what the standard says about this. Is that malloc in the example code undefined behavior, or is it only the access to s->string which is invalid, or is it something else entirely?


Solution

  • What you do is valid, but accessing s->string[0] or feeding s->string to any function accessing the data is invalid.

    The C99 Standard actually says (§6.7.2.1):

    struct s { int n; double d[]; };

    ...

    struct s t1 = { 0 }; // valid

    ...

    The assignment to t1.d[0] is probably undefined behavior, but it is possible that

    sizeof (struct s) >= offsetof(struct s, d) + sizeof (double)

    in which case the assignment would be legitimate. Nevertheless, it cannot appear in strictly conforming code.