Is sizeof a function or an operator?
Asked Answered
C

7

7

Why do we say sizeof(variable) is an operator, not a function?

It looks like a function call and when I am thinking about the meaning of operator, it appears to me something like + or - or * and so on

Cruz answered 22/1, 2021 at 15:41 Comment(4)
Because sizeof (all one word) is an operator, not a function, for example sizeof myvar. It needs parentheses for a type.Prepotency
You only need parens if what follows is an expression.Acetal
You can write x = +(y). The parentheses do not make + a function.Geber
Does this answer your question? Why is sizeof considered an operator?Flypaper
H
8

It's an operator, and you don't need to use brackets, except "when the operand is a type name, it must be enclosed in parentheses". This is a syntax restriction, but should not be confused with a function call.

See the last example below from the GNU documentation:

size_t a = sizeof(int);
size_t b = sizeof(float);
size_t c = sizeof(5);
size_t d = sizeof(5.143);
size_t e = sizeof a;

Without parentheses for a type name, you may see an error like this, with the gcc compiler:

test.c:7:20: error: expected expression before ‘int’
    7 |  size_t s = sizeof int;
      |                    ^~~

But doing sizeof 12 or sizeof a is fine.

Histogen answered 22/1, 2021 at 15:47 Comment(0)
N
5

It's an operator because it doesn't take arguments like a function does. It operates at the syntax level.

f(int) is not a valid function call, but sizeof(int) is a valid use of sizeof.

It can also operate on variables or types, it's quite flexible by design, which is something an operator can do as it's baked deep into the C syntax.

More details can be found here.

Nonagenarian answered 22/1, 2021 at 15:44 Comment(3)
sizeof int is not specified by the C standard.Restrainer
@EricPostpischil Is that a C++-ism?Nonagenarian
Are you thinking of sizeof expression rather than sizeof (type)?Restrainer
C
3

As the grammar indicates:

unary-expression:
  postfix-expression
  ++ unary-expression
  -- unary-expression
  unary-operator cast-expression
  sizeof unary-expression
  sizeof (type-name)
  _Alignof (type-name)

unary-operator: one of
  & * + - ~ !

it's an operator that not only does not require parentheses when taking an unary-expression argument, but it behaves differently with parentheses than a function call would.

Consider that given _Static_assert(sizeof(0)==4,"");, the following holds:

_Static_assert(sizeof(0)==4,"");
int takeIntGive4(int X){ (void)X; return 4; }

#include <assert.h>
int main()
{
    assert(sizeof(0)["foobar"] == 1  && 1 == sizeof(char)); //if sizeof were more function-like you'd get 'a'
    assert(takeIntGive4(0)["foobar"] == 'a');
}

In other words, even though sizeof(0) == takeIntGive4(0) is true on this platform, you can't always just replace takeIntGive4(0) with sizeof(0) because sizeof has a lower precedence than a function call and sizeof(0)["foobar"] will be interpreted as sizeof( (0)["foobar"] ), not (sizeof(0))["foobar"] like it would be if sizeof() were a function.

You can make sizeof function-like, by wrapping it in a macro that parenthesizes it:

#define SIZEOF(X) (sizeof(X))

but keep in mind that sizeof also additionally returns integer constant expressions (except when used with variable-length arrays (VLAs)), which you can use in case labels, bitfield sizes, and array sizes and which function call expressions are incapable of returning.

Centerboard answered 22/1, 2021 at 16:18 Comment(0)
B
2

It is an operator because it is built into the language. Just like + or < it is included in the language grammar. Because of this the sizeof operator can be evaluated when a program is compiled, unlike a user-defined function. For example we can define a function macro which returns the length of a (non-variable length) array:

#define LENGTH(array) (sizeof (array) / sizeof (array)[0])

The length expression is calculated when the program is compiled. At run-time the length of an array is not available (unless you store it in a separate variable).

Bram answered 22/1, 2021 at 15:47 Comment(4)
sizeof is generally not evaluated during compilation for variable length arrays.Restrainer
And most uses of arithmetic and relational operators cannot be evaluated at compile time.Burnside
@EricPostpischil Thanks for the information. I have update the answer.Bram
@JohnBollinger Indeed, the operands must be constant expressions.Bram
G
2

It's an operator that's evaluated at compile-time.

In fact, it only requires the function-like syntax sizeof(T) when T is a type and not an instance of a type.

So, for example, if you have a variable int x, sizeof x is permissible; but sizeof(int) is required for the type int.

Guerra answered 22/1, 2021 at 15:53 Comment(1)
sizeof is a compile time constant (technically: necessarily qualifies as an integer constant) only if its operand does not have variable length array type.Restrainer
N
1

sizeof is an operator. It is listed among the list of unary operators in section 6.5.3p1 of the C standard:

6.5.3 Unary operators

Syntax

unary-expression:
  postfix-expression
  ++ unary-expression
  -- unary-expression
  unary-operator cast-expression
  sizeof unary-expression
  sizeof (type-name)
  _Alignof (type-name)

unary-operator: one of
  & * + - ~ !

As shown above it has two forms. The first form is sizeof followed by an expression. Note that in this form parenthesis are not required, unlike in a function call where they are. The second form is sizeof followed by a type name in parenthesis. Only the second form requires parenthesis, and a function cannot be passed a type name.

It is further referred to as an operator in section 6.5.3.4:

6.5.3.4 The sizeof and _Alignof operators

...

2 The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant

Nichellenichol answered 22/1, 2021 at 16:2 Comment(0)
A
0

Is sizeof a function or an operator?
Why we said sizeof(variable) is operator not function?

In addition to what other have answered, code can take the address of a function, but not the address of sizeof. Much like can cannot take the address of = or *.

size_t (*f1)() = strlen;
size_t (*f2)() = sizeof;
//                     ^ error: expected expression before ';' token

With objects, the () are not needed with sizeof, unlike a function call.

char array[42];
size_t n1 = sizeof array;
size_t n2 = strlen(array) + 1;
 

sizeof can be used with types, not so with a function call.

size_t sz1 = sizeof(double);
size_t sz2 = printf(double);
//                  ^ error: expected expression before 'double'
Acorn answered 22/1, 2021 at 17:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.