Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does sizeof(my_arr)[0] compile and equal sizeof(my_arr[0])?

Tags:

c

sizeof

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.


You're using the version of the sizeof operator that takes an expression as parameter. Unlike the one that takes a type, it doesn't require parentheses. Hence, the operand is simply (my_arr)[0], with the parentheses being redundant.