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
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, 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'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.
sizeof int
is not specified by the C standard. –
Restrainer sizeof expression
rather than sizeof (type)
? –
Restrainer 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.
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).
sizeof
is generally not evaluated during compilation for variable length arrays. –
Restrainer 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
.
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 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'
© 2022 - 2024 — McMap. All rights reserved.
sizeof
(all one word) is an operator, not a function, for examplesizeof myvar
. It needs parentheses for a type. – Prepotencyx = +(y)
. The parentheses do not make+
a function. – Geber