8

I read a question earlier that was closed due to being an exact duplicate of this

When a function has a specific-size array parameter, why is it replaced with a pointer?

and

How to find the 'sizeof' (a pointer pointing to an array)?

but after reading this I am still confused by how sizeof() works. I understand that passing an array as an argument to a function such as

  void foo(int a[5])

will result in the array argument decaying to a pointer. What I did not find in the above 2 question links was a clear answer as to why it is that the sizeof() function itself is exempt from (or at least seemingly exempt from) this pointer decay behaviour. If sizeof() behaved like any other function then

   int a[5] = {1,2,3,4,5};
   cout << sizeof(a) << endl;

then the above should output 4 instead of 20. Have I missed something obvious as this seems to be a contradiction of the decay to pointer behaviour??? Sorry for bringing this up again but I really am having a hard time of understanding why this happens despite having happily used the function for years without really thinking about it.

Community
  • 1
  • 1
mathematician1975
  • 21,161
  • 6
  • 59
  • 101
  • 3
    Note: `void foo(int (&a)[5])` will *not* cause the array argument to decay. It's the target that's important, not the source. – Xeo Jul 01 '12 at 15:45
  • 3
    `void foo(int a[5])` -- I really wish that parameter form would be deprecated and only the form `void foo(int* a)` be allowed, it causes nothing but confusion. I don't care who's code it breaks. – Benjamin Lindley Jul 01 '12 at 16:14

2 Answers2

16

Because the standard says so (emphasis mine):

(C99, 6.3.2.1p3) "Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object and is not an lvalue."

Note that for C++, the standard explicitly says the size is the size of the array:

(C++11, 5.3.3p2 sizeof) "[...] When applied to an array, the result is the total number of bytes in the array. This implies that the size of an array of n elements is n times the size of an element."

ouah
  • 142,963
  • 15
  • 272
  • 331
  • In C++ the rule is slightly different, it has another case where decay doesn't happen: when binding an array expression to an array reference. But those are odd things. See also http://stackoverflow.com/questions/3368883/how-does-this-size-of-array-template-function-work – MSalters Jul 01 '12 at 21:52
7

sizeof is an operator, not a function. It's a specific one at that, too. The parentheses aren't even necessary if it's an expression:

int a;
sizeof (int); //needed because `int` is a type
sizeof a; //optional because `a` is an expression
sizeof (a); //^ also works 

As you can see, it's on this chart of precedence as well. It's also one of the non-overloadable operators.

chris
  • 60,560
  • 13
  • 143
  • 205