When Should We Use Sizeof with and Without Parentheses

When should we use sizeof with and without parentheses

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.

Why (and when) do I need to use parentheses after sizeof?

According to 6.5.3, there are two forms for sizeof as the following:

sizeof unary-expression
sizeof ( type-name )

Since arr in your code is a type-name, it has to be parenthesized.

What does sizeof without () do?

So if we look at the grammar for sizeof in the C99 draft standard section 6.5.3 Unary operators paragraph 1 it is as follows:

sizeof unary-expression
sizeof ( type-name )

There is a difference you can not use a type-name without parenthesizes and section 6.5.3.4 The sizeof operator paragraph 2 says(emphasis mine):

The sizeof operator yields the size (in bytes) of its operand, which may be an
expression or the parenthesized name of a type.[...]

For completeness sake you may wonder if we can use sizeof with an expression if we have parenthesizes and the answer is yes since a unary-expression can itself contain parenthesizes. The easiest way to see this would be to look section A.2.1 Expressions from the draft standard and work through the grammar like so:

unary-expression -> postfix-expression -> primary-expression -> ( expression )

The result of sizeof depends on the location of the brackets. Why?

This expression

sizeof x+y

is equivalent to the expression

( sizeof x ) + y

So as sizeof x is equal to sizeof( float ) that is 4 then the result of the original expression is equal to 9.

The operator sizeof is an unary operator and its operand is in turn an unary expression. That is the operator in particularly is defined like

sizeof unary-expression

x + y is an additive expression while the variable x as a primary expression is in turn an unary expression. Thus the operator is applied to the variable x.

On the other hand, the expression ( x + y ) is a primary expression and due to the usual arithmetic conversions has the type float. So in this case that is when the expression is written like sizeof( x + Y ) the operator sizeof is again applied to a primary (unary) expression and is equivalent to sizeof( float ).

Pay attention to that instead of the conversion specifier %u you shall use the conversion specifier %zu in the calls of printf. The type of the both expressions sizeof x + y and sizeof( x + y ) is size_t that is an implementation defined type that usually is an alias for the type unsigned long. For the type size_t there is defined the conversion specifier zu that you shall use. Otherwise a call of printf with an incorrect conversion specifier can invoke undefined behavior.

Where does C++20 prohibit sizeof...T (without parentheses)

It's required by the grammar:

[expr.unary.general]/1

unary-expression:

      ...

      sizeof ... ( identifier )

      ...

Difference between sizeof(name) and sizeof name

No sizeof isn't a library function, it's a special operator keyword.

It has two forms: One is with parentheses to get the size of a type. The other is not using parentheses and is for getting the size of the result of a generic expression.

With sizeof(name) you're really using the second variant, with the expression (name). I.e. the parentheses are part of the expression and not the sizeof operator.

Why is sizeof considered an operator?

Because the C standard says so, and it gets the only vote.

As consequences:

  • The operand of sizeof can be a parenthesised type, sizeof (int), instead of an object expression.
  • The parentheses are unnecessary: int a; printf("%d\n", sizeof a); is perfectly fine. They're often seen, firstly because they're needed as part of a type cast expression, and secondly because sizeof has very high precedence, so sizeof a + b isn't the same as sizeof (a+b). But they aren't part of the invocation of sizeof, they're part of the operand.
  • You can't take the address of sizeof.
  • The expression which is the operand of sizeof is not evaluated at runtime (sizeof a++ does not modify a).
  • The expression which is the operand of sizeof can have any type except void, or function types. Indeed, that's kind of the point of sizeof.

A function would differ on all those points. There are probably other differences between a function and a unary operator, but I think that's enough to show why sizeof could not be a function even if there was a reason to want it to be.



Related Topics



Leave a reply



Submit