With C, there are no arrays when passed to functions. All the function actually gets when "passed an array", is a pointer -- an address at which it may assume there is some data, spanning some unknown length. It may assume the pointer points to a number of elements of some known type, but it would not know how many. Would you know, given a note with an address written on it, the kind and more importantly the size or number of propertie(s) at the address?
The only way such a function even knows the type of elements of the array, is because a pointer has a type -- for example, with int * var
the function assumes the array is made of a number of int
elements in memory, back to back.
The value of var
inside foo
is the same value as a
, an address. That value is indeed pushed onto the stack when calling foo
. Since foo
returns var
, because var
was what it was passed, pa
is assigned this value and will thus also be the same address as var
and a
.
The name an array is declared with may always be used as a pointer to the array, the address of the array in memory. This pointer, however, may only exist in the same sense you can say the address of your house exists -- there certainly is an address to your house which can be shared with others to locate your house, but it does not necessarily imply the actual plate on the side of your house. That's storing the address. With an expression like pa = foo(...)
, pa
is such a pointer, there is actually allocated (for as long as pa
needs to live, as defined by scoping rules) space in memory to hold an address, and the value of the pointer is stored there.
Your array is stored in memory and foo
, for instance, knows where, because it is passed the address of the array, although it must assume the span of the array (its length). The type of the pointer is how foo
knows how the array is partitioned into elements.
Consequently, with return &var
, as shown in your second variant of foo
, the address of the value storing the address of the array defined with a
, is returned. Put another way, you are returning the address of where an address is stored. The analogy with your house would be you telling your friend where to find a note with the address of your house written on it, i.e. the address (location) of the note with an address of the house written on it.
See also Why do arrays in C decay to pointers?