简体   繁体   English

function 的 sizeof 还是运算符?

[英]Is sizeof a function or an operator?

Why do we say sizeof(variable) is an operator, not a function?为什么我们说sizeof(variable)是运算符,而不是 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它看起来像一个 function 调用,当我考虑运算符的含义时,在我看来像+-*等等

It's an operator because it doesn't take arguments like a function does.它是一个运算符,因为它不像 function 那样需要 arguments。 It operates at the syntax level.它在语法级别运行。

f(int) is not a valid function call, but sizeof(int) is a valid use of sizeof . f(int)不是有效的 function 调用,但sizeof(int)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.它还可以对变量或类型进行操作,它的设计非常灵活,这是操作员可以做的事情,因为它深入到 C 语法中。

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.这是一个语法限制,但不应与 function 调用混淆。

See the last example below from the GNU documentation :请参阅下面来自 GNU 文档的最后一个示例:

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:如果类型名称没有括号,使用 gcc 编译器时,您可能会看到如下错误:

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

But doing sizeof 12 or sizeof a is fine.但是做sizeof 12sizeof a很好。

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.因此,可以在编译程序时评估sizeof运算符,这与用户定义的 function 不同。 For example we can define a function macro which returns the length of a (non-variable length) array:例如,我们可以定义一个 function 宏,它返回一个(非可变长度)数组的长度:

#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.实际上,它仅在T是类型而不是类型的实例时才需要类似函数的语法sizeof(T)

So, for example, if you have a variable int x , sizeof x is permissible;因此,例如,如果您有一个变量int x ,则sizeof x是允许的; but sizeof(int) is required for the type int .但是 int 类型需要sizeof(int) 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.它是一个运算符,在采用一unary-expression参数时不仅不需要括号,而且使用括号的行为与 function 调用不同。

Consider that given _Static_assert(sizeof(0)==4,"");考虑给定_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还额外返回 integer 常量表达式(与可变长度 arrays (VLA) 一起使用时除外),您可以在case标签、位域大小和数组大小中使用它,并且 ZC1C425268E68385D11AB5074C 可调用表达式是可返回的。

sizeof is an operator . sizeof是一个运算符 It is listed among the list of unary operators in section 6.5.3p1 of the C standard :它列在C 标准的第 6.5.3p1 节中的一元运算符列表中:

6.5.3 Unary operators 6.5.3 一元运算符

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.如上图所示,它有两个 forms。 The first form is sizeof followed by an expression.第一种形式是sizeof后跟一个表达式。 Note that in this form parenthesis are not required, unlike in a function call where they are.请注意,在这种形式中括号不是必需的,这与它们所在的 function 调用不同。 The second form is sizeof followed by a type name in parenthesis.第二种形式是sizeof后跟括号中的类型名称。 Only the second form requires parenthesis, and a function cannot be passed a type name.只有第二种形式需要括号,并且不能向 function 传递类型名称。

It is further referred to as an operator in section 6.5.3.4:它在第 6.5.3.4 节中进一步称为运算符:

6.5.3.4 The sizeof and _Alignof operators 6.5.3.4 sizeof_Alignof运算符

... ...

2 The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. 2 sizeof运算符产生其操作数的大小(以字节为单位),它可以是表达式或类型的括号名称。 The size is determined from the type of the operand.大小由操作数的类型决定。 The result is an integer.结果是 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否则,不计算操作数,结果为 integer 常量

Is sizeof a function or an operator? function 的 sizeof 还是运算符?
Why we said sizeof(variable) is operator not function?为什么我们说 sizeof(variable) 不是 function 的运算符?

In addition to what other have answered, code can take the address of a function, but not the address of sizeof .除了其他已回答的内容外,代码可以获取 function 的地址,但不能获取sizeof的地址。 Much like can cannot take the address of = or * .很像 can 不能获取=*的地址。

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.对于对象, sizeof不需要() ,这与 function 调用不同。

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. sizeof可以与types一起使用,而不是与 function 调用一起使用。

size_t sz1 = sizeof(double);
size_t sz2 = printf(double);
//                  ^ error: expected expression before 'double'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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