Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is useful about a reference-to-array parameter?

I recently found some code like this:

typedef int TenInts[10]; void foo(TenInts &arr); 

What can you do in the body of foo() that is useful, that you could not do if the declaration was:

void foo(int *arr);    // or, void foo(int arr[]);   // or, void foo(int arr[10]); // ? 

I found a question that asks how to pass a reference to an array. I guess I am asking why.

Also, only one answer to "When is pointer to array useful?" discussed function parameters, so I don't think this is a duplicate question.

like image 271
Dan Avatar asked Feb 03 '10 00:02

Dan


People also ask

What is a reference to an array?

Reference to an array means aliasing an array while retaining its identity. Reference to an array will not be an int* but an int[].

How are arrays used as parameters?

To pass an array as a parameter to a function, pass it as a pointer (since it is a pointer). For example, the following procedure sets the first n cells of array A to 0. Now to use that procedure: int B[100]; zero(B, 100);

Why are arrays passed by reference?

lang. Object as its supertype, and inherits the implementation of all methods in the Object API. Like all Java objects, arrays are passed by value ... but the value is the reference to the array. Real passing by reference involves passing the address of a variable so that the variable can be updated.

How do you send an array by reference?

How to pass an array by reference in C++ If we pass the address of an array while calling a function, then this is called function call by reference. The function declaration should have a pointer as a parameter to receive the passed address, when we pass an address as an argument.


1 Answers

The reference-to-array parameter does not allow array type to decay to pointer type. i.e. the exact array type remains preserved inside the function. (For example, you can use the sizeof arr / sizeof *arr trick on the parameter and get the element count). The compiler will also perform type checking in order to make sure the array argument type is exactly the same as the array parameter type, i.e. if the parameter is declared as a array of 10 ints, the argument is required to be an array of exactly 10 ints and nothing else.

In fact, in situations when the array size is fixed at compile-time, using a reference-to-array (or pointer-to-array) parameter declarations can be preceived as the primary, preferred way to pass an array. The other variant (when the array type is allowed to decay to pointer type) are reserved for situations when it is necessary to pass arrays of run-time size.

For example, the correct way to pass an array of compile-time size to a function is

void foo(int (&arr)[10]); // reference to an array 

or

void foo(int (*arr)[10]); // pointer to an array 

An arguably incorrect way would be to use a "decayed" approach

void foo(int arr[]); // pointer to an element // Bad practice!!! 

The "decayed" approach should be normally reserved for arrays of run-time size and is normally accompanied by the actual size of the array in a separate parameter

void foo(int arr[], unsigned n); // pointer to an element // Passing a run-time sized array 

In other words, there's really no "why" question when it comes to reference-to-array (or pointer-to-array) passing. You are supposed to use this method naturally, by default, whenever you can, if the array size is fixed at compile-time. The "why" question should really arise when you use the "decayed" method of array passing. The "decayed" method is only supposed to be used as a specialized trick for passing arrays of run-time size.

The above is basically a direct consequence of a more generic principle. When you have a "heavy" object of type T, you normally pass it either by pointer T * or by reference T &. Arrays are no exception from this general principle. They have no reason to be.

Keep in mind though that in practice it is often makes sense to write functions that work with arrays of run-time size, especially when it comes to generic, library-level functions. Such functions are more versatile. That means that often there's a good reason to use the "decayed" approach in real life code, Nevertheless, this does not excuse the author of the code from recognizing the situations when the array size is known at compile time and using the reference-to-array method accordingly.

like image 119
AnT Avatar answered Oct 02 '22 08:10

AnT