4

Possible Duplicate:
What is useful about a reference-to-array parameter?

Are

void myFunction( int (&arg)[4] );

and

void myfunction(int arg[4]);

different? How are they different? What do the first do and how can I call it?

Community
  • 1
  • 1
Chin
  • 19,717
  • 37
  • 107
  • 164

1 Answers1

7

They are different. The first one takes a reference to an array of 4 ints as its argument. The second one takes a pointer to the first element of array of an unknown number of ints as its argument.

int array1[4] = {0};
int array2[20] = {0};

void myFunction1( int (&arg)[4] );
void myFunction2( int arg[4] );

myFunction1( array1 ); // ok
myFunction1( array2 ); // error, size of argument array is not 4

myFunction2( array1 ); // ok
myFunction2( array2 ); // ok
Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • why unknown number of ints? isn't there a 4 in the bracket? – Chin Oct 17 '12 at 15:16
  • 3
    @Chin: In a function signature a type *array of N elements of type T* is converted to *pointer to T* as per the standard. That does not happen if the type is *reference to array of ...*. The reason is that in C (where C++ got this behavior from) you cannot pass an array by value, as it could be an expensive operation. So when you use the syntax to pass by value an array the function will take a pointer and at the call site the array will decay into a pointer to the first element. – David Rodríguez - dribeas Oct 17 '12 at 15:20
  • 2
    The first dimension of an array in a function parameter is always discarded. So having the 4 there doesn't make any difference. – Praetorian Oct 17 '12 at 15:20
  • So is it in both cases, the array is pass by value? – Chin Oct 17 '12 at 16:14
  • 1
    @Chin Not sure what you mean by *pass by value*. In neither case does the function get a copy of the array. In the first it is a reference to the array (which preserves size information) and modifying the array in the function will modify it in the caller's context as well. Similarly, in the second case, it is a pointer to the first element, and you can make modifications to the array using that pointer. – Praetorian Oct 17 '12 at 16:19
  • ouch, I mean pass by reference. Sorry – Chin Oct 17 '12 at 16:36
  • so which approach is more preferable? ie pass a pointer to the array or a reference to it? – Chin Oct 17 '12 at 16:47
  • @DavidRodríguez-dribeas "as it could be an expensive operation" of course C lets you pass a struct by value which contains an array... I would chalk C's bad behavior wrt arrays up to history rather than legitimate performance concerns. (Prior to C's standardization there were a lot more crazy inconsistencies in various C implementations; we're just lucky that the issues with arrays are about the worst that survived into the standard.) – bames53 Oct 17 '12 at 17:05
  • 1
    @Chin First you should just avoid using raw arrays because of this and other problems with them. In C++ if you need a statically sized array just use std::array. If you need a dynamically sized array use std::vector or some other container (or iterators). If you must use raw arrays for whatever reason then use a reference (or other type that preserves the full type information) if possible, because it provides better type checking. Use decayed arrays only as a last resort. – bames53 Oct 17 '12 at 17:13