What happens if I define a 0-size array in C/C++?

As per the standard, it is not allowed.

However it's been current practice in C compilers to treat those declarations as a flexible array member (FAM) declaration:

C99 6.7.2.1, §16: As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member.

The standard syntax of a FAM is:

struct Array {
  size_t size;
  int content[];
};

The idea is that you would then allocate it so:

void foo(size_t x) {
  Array* array = malloc(sizeof(size_t) + x * sizeof(int));

  array->size = x;
  for (size_t i = 0; i != x; ++i) {
    array->content[i] = 0;
  }
}

You might also use it statically (gcc extension):

Array a = { 3, { 1, 2, 3 } };

This is also known as tail-padded structures (this term predates the publication of the C99 Standard) or struct hack (thanks to Joe Wreschnig for pointing it out).

However this syntax was standardized (and the effects guaranteed) only lately in C99. Before a constant size was necessary.

  • 1 was the portable way to go, though it was rather strange.
  • 0 was better at indicating intent, but not legal as far as the Standard was concerned and supported as an extension by some compilers (including gcc).

The tail padding practice, however, relies on the fact that storage is available (careful malloc) so is not suited to stack usage in general.


An array cannot have zero size.

ISO 9899:2011 6.7.6.2:

If the expression is a constant expression, it shall have a value greater than zero.

The above text is true both for a plain array (paragraph 1). For a VLA (variable length array), the behavior is undefined if the expression's value is less than or equal to zero (paragraph 5). This is normative text in the C standard. A compiler is not allowed to implement it differently.

gcc -std=c99 -pedantic gives a warning for the non-VLA case.

Tags:

C++

C

Arrays