32
typedef struct rem{
    int  addr;
    char addrbuf[32];
} foo;

Both of these codes return the same results

foo addr;
printf("size is: %d\n",sizeof addr);
printf("size is: %d\n",sizeof (foo));

size is: 36

size is: 36

But when should we use sizeof with and without parentheses?

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
cmidi
  • 1,880
  • 3
  • 20
  • 35

2 Answers2

48

When using sizeof with a type, you need parentheses around the type. When using it with an expression, you don't. But you can of course include them in this case as well, and you don't have to worry about operator precedence in such case. With uncommon operators such as this one, fewer people would be sure of the precedence, so clarity certainly helps.

So I'd say it's preferable to use them always.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • That is what I was thinking thanks for clearing my doubt. – cmidi Jan 21 '15 at 19:23
  • 10
    Nit: depending on the expression, you may still need parentheses even then. `sizeof a + b` doesn't mean `sizeof (a + b)`. (I know that's what you meant too.) –  Jan 21 '15 at 19:23
  • @hvd That's why I mentioned (and now elaborated on) operator precedence. – Angew is no longer proud of SO Jan 21 '15 at 19:23
  • @hvd: There's no parentheses around that expression. There are parentheses inside the expression, of course, controlling parsing. – Ben Voigt Jan 21 '15 at 19:24
  • 5
    A worse situation would be `char x[10]; sizeof(x + 1)` will be very different from `sizeof x + 1`. – Iharob Al Asimi Jan 21 '15 at 19:25
  • Yeah, I didn't think you thought otherwise. :) @BenVoigt In `sizeof (a + b)`, there are parentheses around the expression `a + b`. –  Jan 21 '15 at 19:25
  • @hvd: But the expression `a + b` is not the operand of `sizeof`. The expression `(a + b)` is. There are no parentheses around the operand. – Ben Voigt Jan 21 '15 at 19:26
  • @BenVoigt Let me rephrase, then. If you have the expression `a + b`, and want to use it as an operand of `sizeof`, you cannot do so directly, you need to first put parentheses around it. And you're right that that makes `(a + b)` the operand of `sizeof`. –  Jan 21 '15 at 19:28
  • 4
    @hvd: It's also important to note that parentheses may be required around `sizeof operand`. Consider `char a; int x = sizeof(a)["abcdef"];` What is `x` ? Would you know whether that is equivalent to `sizeof (a["abcdef"])` or `(sizeof a)["abcdef"]` ? Very confusing to people who assume the `()` are part of the sizeof syntax. – Ben Voigt Jan 21 '15 at 19:34
  • @BenVoigt I would, because a common use of `sizeof` is `sizeof array / sizeof array[0]`, so I'm well aware that `[0]` is part of the operand of `sizeof`. :) To disambiguate, when `(sizeof a)["abcdef"]` is meant, I would strongly prefer `"abcdef"[sizeof a]`, without a need for parentheses around `sizeof a`. –  Jan 21 '15 at 19:37
  • @hvd: Of course. But it comes as a surprise to people who think that `sizeof (expression)` takes care of operator precedence concerns. Of course, for `(sizeof a)` and `[sizeof a]` alike, there's clearly no value to putting parentheses in the operand, doing so just adds line noise. – Ben Voigt Jan 21 '15 at 19:40
  • @hvd: But if "Expressions with unary operators group right-to-left" and `sizeof`, unary `+`, and cast are all the same precedence, why is `sizeof (int)+5` equivalent to `(sizeof (int))+5` and not `sizeof ((int)+5)` ? – Ben Voigt Jan 21 '15 at 19:44
  • @BenVoigt; In `sizeof (int)+5`, `+` will be treated as binary `+` and `(int)` will go with `sizeof`. In `sizeof ((int)+5)`, no evaluation of operand takes place and it will return the size of type. – haccks Jan 21 '15 at 19:59
  • 1
    @BenVoigt What haccks said, but also, "Expressions with unary operators group right-to-left" isn't something I've said, and I'm not sure what you're quoting from. The C grammar is clear that `sizeof`'s expression operand must be a *unary-expression*, not a *cast-expression*. –  Jan 21 '15 at 20:04
  • @hvd: The quoted text is straight from the Standard. But actually, you're right, casts have their own grammar production not mixed with *unary-expression*. So the precedence table on Wikipedia is wrong. – Ben Voigt Jan 21 '15 at 20:39
  • @BenVoigt Ah, sorry, the question is tagged both C and C++, and I was looking at the C standard, which does not contain those same words. –  Jan 21 '15 at 20:53
  • It's because `sizeof`has priority over `+`: https://en.cppreference.com/w/c/language/operator_precedence @iharob – Sandburg Aug 14 '19 at 10:44
15

[expr.sizeof]/1:

The operand is either an expression, which is an unevaluated operand (Clause 5), or a parenthesized type-id.

Thus the parentheses are required for types only. If you prefer to use parentheses for clarity and consistency (as I do) you can always use them though, as parentheses around an expression form another expression.
The operator precedence of sizeof is not very well known and could cause irritations.

Also, for the sizeof... operator, you always have to use parentheses (another reason for consistency).

Columbo
  • 60,038
  • 8
  • 155
  • 203