4

I learned to program in C many years ago, and used C steadily for about 10 years.

These days, I occasionally have to look at C code, because our Informix 4GL RDS customized runners also contain C code, but it is fairly simplistic code.

When I was using C a lot, I never remember hearing about of flexible arrays. I am asking this question, because I came across this SO question. Thanks.

3 Answers 3

5

It is defined in ISO C99; I don't really know if it has been defined before, but I doubt it.

Traditionally, structures with now-specified flexible arrays were declared with arrays of size 1 at the end, and then allocated according to the desired size, a trick known as the "struct hack". Examples of this may be seen eg. in the Windows API.

1
  • 1
    Flexible array members definitely were not standardized before C99; they didn't appear in the 1995 revision of the 1990 ISO C standard. Jun 24, 2012 at 20:03
8

There are two different things that the C99 standard added and they are easy to mix up by mistake:

Flexible array members. This means that a struct can have a member of unknown size at the end. Example from the C standard:

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

int m = /* some value */;
struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));

This was used before C99 as well, but it was then undefined behavior, known as the "struct hack" referred to in another answer. Before C90, there could be unexpected padding bytes at the end of the struct, leading to bugs.

Variable length arrays (VLA). These are arrays with their size set in runtime. They are most likely implemented by the compiler by using dynamic memory allocation. Example:

void func (int n)
{
  int array[n];
}
1

C99 standardised them. However, they were used long prior with 1-element arrays, a trick known as the struct hack.

It's not clear if it's legal or portable, but it is rather popular. An implementation of the technique might look something like this:

    #include <stdlib.h>
    #include <string.h>

    struct name *makename(char *newname)
    {
        struct name *ret =
            malloc(sizeof(struct name)-1 + strlen(newname)+1);
                    /* -1 for initial [1]; +1 for \0 */
        if(ret != NULL) {
            ret->namelen = strlen(newname);
            strcpy(ret->namestr, newname);
        }

        return ret;
    }

This function allocates an instance of the name structure with the size adjusted so that the namestr field can hold the requested name (not just one character, as the structure declaration would suggest).

Despite its popularity, the technique is also somewhat notorious: Dennis Ritchie has called it ``unwarranted chumminess with the C implementation,'' and an official interpretation has deemed that it is not strictly conforming with the C Standard, although it does seem to work under all known implementations. (Compilers which check array bounds carefully might issue warnings.)

Another possibility is to declare the variable-size element very large, rather than very small...

7
  • AFAIK you're confusing flexible arrays (struct X { int len; double data[]; } and variable-length arrays (int n = get_the_value_somewhere(); int array[n];). They are different.
    – jpalecek
    Jun 24, 2012 at 19:31
  • @jpalecek: I just edited that. Hadn't heard them termed flexible arrays before.
    – DeadMG
    Jun 24, 2012 at 19:32
  • The term flexible arrays, is why I included the link to the post. Jun 24, 2012 at 20:21
  • @octopusgrabbus: You should not have a question where every answer must click a link.
    – DeadMG
    Jun 24, 2012 at 20:23
  • I'm confused. I put the link in my original question, because I had never heard of flexible arrays, and, instead of copying the code here, I thought if anyone wanted to see how that term was used, they could look. Sorry for any protocol misstep. Jun 24, 2012 at 20:27

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.