Hacker News new | ask | show | jobs
by quuxplusone 558 days ago
Not "variables," but "expressions." In both C and C++, `sizeof` is a unary operator that applies to a postfix expression, so e.g. `sizeof a[0]` and `sizeof p->x` are both OK. This can theoretically be confusing, although the only examples I know are silly and/or easily fixed:

In C++, `p->pmf` has surprisingly low precedence, so `sizeof p->pmf` means `sizeof(p) ->* pmf`, which is ill-formed.

https://gcc.gnu.org/onlinedocs/cpp/Operator-Precedence-Probl... shows that "insufficiently hygienic" macros can also cause trouble, e.g. `-DINC(x)=x+1` means that `sizeof INC(1)` is `sizeof 1+1` which is `5`, not, as you might have naïvely expected, `sizeof (1+1)` which is `4`.

Extra parentheses can be used to deceive, too: `sizeof(0[p])` is the same as `sizeof(p[0])`, but `sizeof(0)[p]` is... also the same as `sizeof(p[0])` — not `p[sizeof(0)]` — because the postfix `[]` operator binds tighter than the prefix `sizeof` operator.

Oddly enough, the `alignof` operator officially applies only to types, as in `alignof(T)`; Clang, GCC, and EDG all do support `alignof expr`, but only as a non-standard extension.

2 comments

Surprisingly, the sizeof operator applies to prefix expressions, too, except casting. So sizeof !x works, but sizeof (int)x doesn't, despite ! and casting having the same precedence.

The presence of (int) sort of promotes sizeof from "operator that applies to expressions" to "function that takes a type". I think this is a side effect of reusing the same keyword for two syntactically different constructs.

Thank you very much for that clarification. I knew about using sizeof with expressions, but I so rarely used it that way that I never gave it much thought.