Why does sizeof(my_arr)[0] compile and equal sizeof(my_arr[0])?
sizeof
is not a function. It's a unary operator like !
or ~
.
sizeof(my_arr)[0]
parses as sizeof (my_arr)[0]
, which is just sizeof my_arr[0]
with redundant parentheses.
This is just like !(my_arr)[0]
parses as !(my_arr[0])
.
In general, postfix operators have higher precedence than prefix operators in C. sizeof *a[i]++
parses as sizeof (*((a[i])++))
(the postfix operators []
and ++
are applied to a
first, then the prefix operators *
and sizeof
).
(This is the expression version of sizeof
. There's also a type version, which takes a parenthesized type name: sizeof (TYPE)
. In that case the parens would be required and part of the sizeof
syntax.)
sizeof
has two "versions": sizeof(type name)
and sizeof expression
. The former requires a pair of ()
around its argument. But the latter - the one with an expression as an argument - does not have ()
around its argument. Whatever ()
you use in the argument is seen as part of the argument expression, not part of sizeof
syntax itself.
Since my_arr
is known to the compiler as an object name, not a type name, your sizeof(my_arr)[0]
is actually seen by the compiler as sizeof
applied to an expression: sizeof (my_arr)[0]
, where (my_arr)[0]
is the argument expression. The ()
surrounding the array name is purely superfluous. The whole expression is interpreted as sizeof my_arr[0]
. This is equivalent to your previous sizeof(my_arr[0])
.
(This means, BTW, that your previous sizeof(my_arr[0])
also contains a pair of superfluous ()
.)
It is a rather widespread misconception that sizeof
's syntax somehow requires a pair of ()
around its argument. This misconception is what misleads people's intuition when interpreting such expressions as sizeof(my_arr)[0]
.
[]
have a higher precendence than sizeof
. So sizeof(my_arr)[0]
is the same as sizeof((my_arr)[0])
.
Here is a link to a precedence table.