The last good thing written in C was the Pachelbel Canon. - Jerry Olson

the brown-dragon blog

Pass Me The Array

2009-01-06

Have you ever wondered how to pass an array as a return value in C? It's not something commonly done, so I'll walk you through it.

Initially, you may start off reasonably enough:

pmta.syntax-error.c

#define ARRAY_SIZE  25

int [] pass_array ()
{
        int a[ARRAY_SIZE];
        int i;

    for (i = 0;i < ARRAY_SIZE;++i) a[i] = i;

    return a;
}

int
main ()
{
        int a[ARRAY_SIZE];
        int i;

    a   =   pass_array ();

    for (i = 0;i < ARRAY_SIZE;++i)
        printf ("a[%d] = %d\n", i, a[i]);

    return 0;
}

...which will immediately result in a *Syntax Error*.

Dredging up your knowledge of the C declaration syntax you will then come up with the (correct) declaration:

pmta.function-returns-array.c

#define ARRAY_SIZE  25

int (pass_array ()) [ARRAY_SIZE]
{
        int a[ARRAY_SIZE];
        int i;

    for (i = 0;i < ARRAY_SIZE;++i) a[i] = i;

    return a;
}

...in which case the compiler complains that *Function returning Array*! WTF?! That's what you want but the compiler just refuses to do it.

As a side note, the C declaration syntax is not very well designed which is why we see the funky declaration above.

At this point, do NOT allow frustration to force you into the elementary error of returning a pointer:

pmta.eeks.c

#define ARRAY_SIZE  25

int (* pass_array ()) [ARRAY_SIZE]
{
        int a[ARRAY_SIZE];
        int i;

    for (i = 0;i < ARRAY_SIZE;++i) a[i] = i;

    return &a;
}

...which will compile all right but will return a pointer to local (auto) storage. As you undoubtedly learnt at your mother's knee, this is something no good little C programmer ever does!

The correct way to return an array is to simply "wrap" it as a POD (in a struct). This works pretty well:

pmta.c

#define ARRAY_SIZE  25

typedef struct {
    int a[ARRAY_SIZE];
} wrapper;

wrapper pass_array ()
{
        wrapper wrap;
        int i;

    for (i = 0;i < ARRAY_SIZE;++i) wrap.a[i] = i;

    return wrap;
}

int
main ()
{
        wrapper wrap;
        int i;

    wrap = pass_array ();

    for (i = 0;i < ARRAY_SIZE;++i)
        printf ("a[%d] = %d\n", i, wrap.a[i]);

    return 0;
}

See C Run! Run C run! :-D

Other Posts

(ordered by Tags then Date)