0

I can declare animal_array1 and animal_array2. First one on the stack, while the second one is ... well, still on the stack but this time declared as a function parameter. Here is a sample code:

 #include <iostream>

 using namespace std;

 struct Animal
 {
 };

 void test(Animal animal_array2[10])
 {
     Animal animal_array1[10];
     if(sizeof(animal_array2) == sizeof(animal_array1))
         cout << "Both sizes are equal. That's expected!" << endl;
     else
         cout << "Mhhh sizes are *NOT* equal. That wasn't expected at all!" << endl;

 }

 int main()
 {
     Animal unused_var[10];
     test(unused_var);
 }

The output is:

 $./a.out 
 Mhhh sizes are *NOT* equal. That wasn't expected at all!

How can it be? Gcc bug? Or is it standard behavior? How can we get such streched results from the same apparent type?

yves Baumes
  • 8,836
  • 7
  • 45
  • 74
  • 3
    http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c – chris Mar 12 '14 at 17:57
  • 1
    It's important to be aware that there are two distinct rules at play here. One is that a parameter declaration of array type is "adjusted" so that it's really of pointer type; `void func(int arr[10])` really means `void func(int *arr)`. (The fact that the `10` is silently ignored is one of the more annoying features of both C and C++.) The other is that an expression of array type is, in most but not all contexts, implicitly *converted* to a pointer to the array's first element. This latter rule is not specific to functions or function calls. – Keith Thompson Mar 12 '14 at 18:12
  • 1
    @KeithThompson, it's not ignored silently on clang: `warning: sizeof on array function parameter will return size of 'Animal *' instead of 'Animal [10]' [-Wsizeof-array-argument]`. I wish gcc would warn about it too. I don't know if clang warns on all cases where the type difference makes a difference. – eerorika Mar 12 '14 at 18:24

2 Answers2

4

Arrays are the only data types in C and C++ that cannot be passed by value. So an array decays to a pointer to the first element of the array (when declared and passed) as a function parameter.

So basically this:

void test(Animal animal_array2[10])

is actually:

void test(Animal *animal_array2)

but only as function parameter

and the array passed as a parameter:

test(unused_var);

decays to a pointer to the first elem in the array:

test(&(unused_var[0]));

(as a sidenote: but without the actual dereferencing)

bolov
  • 72,283
  • 15
  • 145
  • 224
3

Arrays will decay into pointers when passed to a function in C++. Typically what you do is pass the known size to the function, as a separate parameter. Not in the between the square brackets.

Engineer2021
  • 3,288
  • 6
  • 29
  • 51