Search code examples
c++pass-by-referencepass-by-valuefunction-declaration

If arrays are passed by reference, why should I use int(&)[]?


Consider:

#include <iostream>
using namespace std;

void Change(int arr[3]) {
    for (int i = 0; i < 3; i++) {
        arr[i] = 1;
    }
}

int Test() {
    int arr[3] = { 0, 0, 0 };

    for (int i = 0; i < 3; i++) {
        cout << arr[i] << endl;
    }

    Change(arr);

    for (int i = 0; i < 3; i++) {
        cout << arr[i] << endl;
    }

    return 0;
}

Since arrays are passed by default as a pointer to their first element and not copied, changing the value of an element of the array in a function effectively results in changing the value of that element of the array in the function caller, which is why the above code outputs

0
0
0
1
1
1

If this is the case, then why would anyone need to pass an array like the following?

void Change(int (&arr)[3])

I am aware that the parentheses are needed to make the argument a reference to an array instead of an array of references, but what do I gain?


Solution

  • This function declaration:

    void Change(int arr[3])
    

    is adjusted by the compiler to:

    void Change(int *arr)
    

    So, the function knows nothing about the size of the passed array.

    If you declare the function like:

    void Change(int ( &arr )[3])
    

    then within the function, you can get the size of the array using, for example, the standard function std::size(), or get its first and last iterators like std::begin(arr) and std::end(arr). And moreover, you can pass the array by reference to a template function that accepts its argument by reference, similarly to passing any container.

    Another advantage is that the compiler will check that an array of the required size is passed, and the user of the function can not pass a null pointer to the functon.