Velocity Reviews > C99 Standard, arrays of size omitted

# C99 Standard, arrays of size omitted

Peteris Krumins
Guest
Posts: n/a

 06-27-2003
Hello,

C99 Standard states that the last member of structure can be an array
whose size is omitted. What's the point of having such member in a
structure and how can it be effectivly used?

struct foo {
int value;
long another;
char arr[0];
};

Also can i simply have a variable (array) which has size omitted?

int omitted[0];
char *pointers[0]; /* is this valid too? */

P.Krumins

Simon Biber
Guest
Posts: n/a

 06-28-2003
"Peteris Krumins" <(E-Mail Removed)> wrote:
> Hello,
>
> C99 Standard states that the last member of structure can be
> an array whose size is omitted. What's the point of having
> such member in a structure and how can it be effectivly
> used?
>
> struct foo {
> int value;
> long another;
> char arr[0];
> };

Actually, you didn't omit the size, you made it zero, which is
wrong.

The proper C99 syntax is:
struct foo {
int value;
long another;
char arr[];
};

The way you use it is usually with malloc:
struct foo *p = malloc(n + sizeof *p);
if(p != NULL)
{
/* Now p->arr has n elements available. */
/* ... */
free(p);
}

This was added because of the *wrong* existing practise to do:
struct foo {
int value;
long another;
char arr[1]; /* Note one element */
};
struct foo *p = malloc(n + sizeof *p - 1);
if(p != NULL)
{
/* Now p->arr is used as if it has n elements available. */
/* ... */
free(p);
}
This is wrong because it is still undefined behaviour to
access an element outside the declared array size of 1.
It does work on most C89 compilers.

> Also can i simply have a variable (array) which has size
> omitted?

Only in a couple of cases. The first dimension of a function
parameter declared using array syntax can have its size
omitted. This is OK because the array size is never used --
the parameter's type is always rewritten into a pointer to
the first element.

For example:
int foo(int arr[][5]);
is rewritten as:
int foo(int (*arr)[5]);

Another example is where you're making a declaration of an
array which is defined in another translation unit:
extern int arr[];

> int omitted[0];
> char *pointers[0]; /* is this valid too? */

Neither of these are valid. Omitting the size does *not*
mean you can make it zero.

--
Simon.