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

482 Views Asked by At

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?

2

There are 2 best solutions below

5
On BEST ANSWER

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.

3
On

At one time, Microsoft C allowed the following:

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

And I used something like this to build a text editor. However, this was a long time ago and I know it was non-standard at the time. I'm not even 100% certain Microsoft still supports it.

The bottom line is that it depends on your compiler, and the current compile settings.