简体   繁体   中英

Is sizeof a function or an operator?

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

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 .

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.

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).

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 .

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,"");
#include <assert.h>
int takeIntGive4(int X){ (void)X; return 4; }
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');
}

You can make it more function-like, by wrapping it in a macro:

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

but 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.

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

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'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM