276

How does passing a statically allocated array by reference work?

void foo(int (&myArray)[100]) { } int main() { int a[100]; foo(a); } 

Does (&myArray)[100] have any meaning or its just a syntax to pass any array by reference? I don't understand separate parenthesis followed by big brackets here. Thanks.

2

5 Answers 5

320

It's a syntax for array references - you need to use (&array) to clarify to the compiler that you want a reference to an array, rather than the (invalid) array of references int & array[100];.

EDIT: Some clarification.

void foo(int * x); void foo(int x[100]); void foo(int x[]); 

These three are different ways of declaring the same function. They're all treated as taking an int * parameter, you can pass any size array to them.

void foo(int (&x)[100]); 

This only accepts arrays of 100 integers. You can safely use sizeof on x

void foo(int & x[100]); // error 

This is parsed as an "array of references" - which isn't legal.

Sign up to request clarification or add additional context in comments.

5 Comments

Why can't we have an array of references e.g. int a, b, c; int arr[3] = {a, b, c};?
Aha, found out why.
Could someone explain why void foo(int & x[100]); is parsed as "array of references" please? Is it because the "from-right-to-left" rule? If yes, it seems to be not consistent with how void foo(int (&x)[100]); is parsed as "a reference to a array". Thanks in advance.
It's not right to left, it's inside out, and [] binds tighter than &.
"This only accepts arrays of 100 integers. You can safely use sizeof on x" is a good clarification to mention.
72

It's just the required syntax:

void Func(int (&myArray)[100]) 

^ Pass array of 100 int by reference the parameters name is myArray;

void Func(int* myArray) 

^ Pass an array. Array decays to a pointer. Thus you lose size information.

void Func(int (*myFunc)(double)) 

^ Pass a function pointer. The function returns an int and takes a double. The parameter name is myFunc.

2 Comments

How do we pass a variable size array as a reference ?
@ShivamArora You templateize the function and make the size a template parameter.
32

It is a syntax. In the function arguments int (&myArray)[100] parenthesis that enclose the &myArray are necessary. if you don't use them, you will be passing an array of references and that is because the subscript operator [] has higher precedence over the & operator.

E.g. int &myArray[100] // array of references

So, by using type construction () you tell the compiler that you want a reference to an array of 100 integers.

E.g int (&myArray)[100] // reference of an array of 100 ints

4 Comments

"if you don't use them, you will be passing an array of references" - which of course, cannot exist, so you'd get a compile error. It's amusing to me that the operator precedence rules insist this must happen by default anyway.
Is there's any more tutorial about type construction () ?
Thanks, I needed an explanation that included the reason about operator precedence, which gives a sense to why it should be done this way.
@BugShotGG, thanks so much for providing me with a head-slap "oh, that's what's causing this" moment by mentioning operator precedence. I guess this is inevitable because [] needs left to right associativity while & needs right to left so they can't be in the same level. And I guess ++/-- need to be above & so pointer incrementation works as expected. Thanks again.
21

The following creates a generic function, taking an array of any size and of any type by reference:

template<typename T, std::size_t S> void my_func(T (&arr)[S]) { // do stuff } 

play with the code.

1 Comment

7

Arrays are default passed by pointers. You can try modifying an array inside a function call for better understanding.

7 Comments

Arrays can not be passed by value. If the function receives a pointer, an array decays to a pointer to its first element. I'm not sure what you are trying to say here.
Array are neither passed by value nor reference. They are passed by pointers. If arrays are passed by reference by default, you will have no problem using sizeof on them. But that is not the case. Arrays decays to pointers when passed into a function.
Arrays can be passed by reference OR by degrading to a pointer. For example, using char arr[1]; foo(char arr[])., arr degrades to a pointer; while using char arr[1]; foo(char (&arr)[1]), arr is passed as a reference. It's notable that the former form is often regarded as ill-formed since the dimension is lost.
Re, "Arrays are...passed by pointers." That description sounds unconventional at best, and it may be confusing to newbies. The name of an array variable, is a valid expression whose value is a pointer the the first member of the array. If you have some function foo(T* t), and you have an array T a[N]; then when you write foo(a); I think it would be more correct to say that you are passing a pointer, not passing an array, and you are passing the pointer by value.
@user3437460 Commenting on old comment since it has a lot of votes: in C++ arrays can be passed by reference.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.