There are several ways to achieve what you want:
The way that does not work
Did you try to compile the code you gave in the question? Then you
probably noticed it does not compile. I tried and got: “error: expected
primary-expression before ‘]’ token”, meaning the compiler expected
return array[some_index];
.
The way that almost works
Remove the brackets and just return array
:
int *function()
{
int array[3];
array[0] = 19;
array[1] = 7;
array[2] = 69;
return array;
}
This may work, or not, depending on the surrounding code, on how the
optimizer processes your program, and on how lucky you are when you test
it. It is called “undefined behaviour” and is something you should
always avoid.
Here is what happens: in C (and C++) you cannot return an array. The
identifier array
“decays” to a pointer pointing at its first element.
Then return array
is essentially equivalent to return &array[0]
. The
problem is that, since the array is allocated in the function's stack
frame, it ceases to exist when the function returns, thus the caller
gets a pointer to an area of memory that is not allocated anymore.
Likely memory corruption ahead. The compiler warned me when I tried to
do that: “warning: address of local variable ‘array’ returned”. It's a
very serious warning that should never be ignored.
The simplest fix: make the array static
As suggested by Chris Stratton in a comment, you can make the array
static, so it will be allocated for the whole life of the program:
int *function()
{
static int array[3];
array[0] = 19;
array[1] = 7;
array[2] = 69;
return array;
}
The only catch is that the function is now not reentrant, meaning that
every time you call it it will clobber the same array it returned on the
previous calls. Depending on your use case, this may not be an issue,
but it's something you need to be aware of.
Have the caller manage the allocation
A safer (reentrant) way is to have the caller provide the memory needed
for the array. This is a very common method in C, and is suggested both
by Harper Shelby's answer and Chris Stratton's comment:
int *function(int array[3])
{
array[0] = 19;
array[1] = 7;
array[2] = 69;
return array;
}
The caller can allocate in static memory, or in it's own stack frame, or
on the heap... but you do not care, the allocation is the caller's
problem now.
A couple of things to note here:
- The prototype is equivalent to
int *function(int *array)
: the
function receives only a pointer. Writing array[3]
instead of
*array
has the sole effect of documenting that the function
expects the pointer to point to somewhere with room for 3 values. You
could document that in a comment instead.
- The function could return
void
, since the caller presumably knows
the address it is giving you. Returning that same address is just for
convenience, as it can help you chain calls like
another_function(function(array))
.
Return the array in a struct
One may wonder: why can't we return an array in the first place. I do
not know for sure why the authors of the language made this choice, but
one possible explanation is that it is expensive to return a big array
by value, as it involves copying the whole of it. Now, if your array is
really only three ints, then that argument does not apply, and you may
reasonably want to really return the whole array by value. This can be
done by embedding it inside a struct:
// Struct definition.
struct Array3 {
int array[3];
};
Array3 function()
{
Array3 a;
a.array[0] = 19;
a.array[1] = 7;
a.array[2] = 69;
return a;
}