What is array to pointer decay?

Arrays are basically the same as pointers in C/C++, but not quite. Once you convert an array:

const int a[] = { 2, 3, 5, 7, 11 };

into a pointer (which works without casting, and therefore can happen unexpectedly in some cases):

const int* p = a;

you lose the ability of the sizeof operator to count elements in the array:

assert( sizeof(p) != sizeof(a) );  // sizes are not equal

This lost ability is referred to as "decay".

For more details, check out this article about array decay.


It's said that arrays "decay" into pointers. A C++ array declared as int numbers [5] cannot be re-pointed, i.e. you can't say numbers = 0x5a5aff23. More importantly the term decay signifies loss of type and dimension; numbers decay into int* by losing the dimension information (count 5) and the type is not int [5] any more. Look here for cases where the decay doesn't happen.

If you're passing an array by value, what you're really doing is copying a pointer - a pointer to the array's first element is copied to the parameter (whose type should also be a pointer the array element's type). This works due to array's decaying nature; once decayed, sizeof no longer gives the complete array's size, because it essentially becomes a pointer. This is why it's preferred (among other reasons) to pass by reference or pointer.

Three ways to pass in an array1:

void by_value(const T* array)   // const T array[] means the same
void by_pointer(const T (*array)[U])
void by_reference(const T (&array)[U])

The last two will give proper sizeof info, while the first one won't since the array argument has decayed to be assigned to the parameter.

1 The constant U should be known at compile-time.