Sizeof &a vs *a

The size of the address depends on your architecture and is not directly related to the size of an int itself. So it’s 8 in your case, which seems pretty normal (64 bits).


The key to understanding this is to know that arrays usually "decay" into pointers to the first element, whenever they are used in an expression. Except for some special cases. The rule of array decay and the exceptions are found in the C standard (C17 6.3.2.1/3):

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.

As we can see, sizeof and & are exceptions to the rule.

This means that a in sizeof(&a) does not decay to a pointer. We can know this because sizeof and unary & are both unary operators with the same precdence, but with right-to-left operator associativity. Meaning that &a gets interpreted first and there is no array decay when & is used.

So we get the address of the array. In your case, the size of an int pointer of type int(*)[10]. What size a pointer got has nothing to do with the size of an int, but it is likely to be either 4 or 8 bytes on 32 and 64 bit systems respectively.

In case of sizeof(*a), then just like in the &a case, the rigth-to-left associativity of unary operators means that *a gets interpreted first. And so the array does decay into a pointer to the first element, before sizeof is applied. So *a gives the size of the first element, which is the size of an int.

And finally in case of sizeof(a) there is no array decay since a is used with sizeof and no other operator is present. Meaning we get the size of the whole array.


sizeof &a == sizeof (int (*)[10]) // pointer to 10-element array of int
sizeof *a == sizeof a[0] == sizeof (int)
sizeof  a == sizeof (int [10])

and just to be complete

 sizeof &a[0] == sizeof (int *)

All of these sizes depend on the underlying platform. Pointer type sizes do not depend on the size of the pointed-to type (there’s no relation between the sizes of an int and an int *). Different pointer types may have different sizes - the only requirements are:

  • char * and void * have the same size and alignment;
  • pointers to qualified types have the same sizes and alignments as their unqualified equivalents (e.g., sizeof (const int *) == sizeof (int *);
  • all struct pointer types have the same size and alignment;
  • all union pointer types have the same size and alignment;

On any modern desktop or server system you're likely to encounter (read: x86), all object pointer types have the same size and alignment. Just be aware that there are oddball architectures out there where that may not be true.

Tags:

C

Sizeof