I have been programming c/c++ for many years, but todays accidental discovery made me somewhat curious... Why does both outputs produce the same result in the code below? (<
The two have the same value but different types.
When it's used by itself (not the operand of &
or sizeof
), arr
evaluates to a pointer to int
holding the address of the first int
in the array.
&arr
evaluates to a pointer to array of three int
s, holding the address of the array. Since the first int
in the array has to be at the very beginning of the array, those addresses must be equal.
The difference between the two becomes apparent if you do some math on the results:
arr+1
will be equal to arr + sizeof(int)
.
((&arr) + 1)
will be equal to arr + sizeof(arr)
== arr + sizeof(int) * 3
Edit: As to how/why this happens, the answer is fairly simple: because the standard says so. In particular, it says (§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.
[note: this particular quote is from the C99 standard, but I believe there's equivalent language in all versions of both the C and C++ standards].
In the first case (arr
by itself), arr
is not being used as the operand of sizeof, unary &, etc., so it is converted (not promoted) to the type "pointer to type" (in this case, "pointer to int").
In the second case (&arr
), the name obviously is being used as the operand of the unary &
operator -- so that conversion does not take place.