c++arrayspointerssizeof

Arrays and sizeof() in C++


It is said that when an array is passed as a parameter to a function, it decays into a pointer and the length of the array needs to be passed as a parameter as well. This implies that the original array stored information about its size. Indeed, sizeof(arr) inside a function body, where arr is an argument of the function, should return 8 (bytes), because that's the size of a pointer in a 64-bit machine. Meanwhile sizeof(arr), when arr is not a parameter, returns the actual size of the whole array in bytes.

#include <iostream>
void foo(int arr[]) {
  // prints 8
  std::cout << sizeof(arr) << "\n";
}

int main() {
  int arr[] = {1, 2, 3, 4, 5};
  // prints 20
  std::cout << sizeof(arr) << "\n";
  // prints 8
  foo(arr);
}

But the name of the array is already a pointer to its first element. arr[i] is just *(arr + i). This leads to a contradiction. Either:

  1. The name of the array is not a pointer to its first element (as I was told). But then what is it? And if it's not a pointer, why is pointer arithmetic with it possible?
  2. The name of the array really is a pointer to the first element. But then why does it keep different information than the pointer it decays into?

Solution

  • This leads to a contradiction.

    No it does not. In certain contexts, an array decays to a pointer to its first element. For example, one case where array does not decay to a pointer is decltype:

    int arr[2];
    decltype(arr) i;     //i is int[2] and array does not decay to a pointer here
    

    Here is one example where it does decay to a pointer to its first element:

    int arr[2]{};
    auto j = arr; //j is int*; here array decays to int*
    

    Another example where array does not decays is:

    char arr[10]{};
    auto k = sizeof(arr); // k is initialized with 10 and array  does not decay to pointer