为什么 sizeof int 是错误的,而 sizeof (int)是正确的?

我们知道,sizeof是一个用于计算任何数据类型和表达式的大小的运算符,当操作数是一个表达式时,可以省略括号。

int main()
{
int a;


sizeof int;
sizeof( int );
sizeof a;
sizeof( a );


return 0;
}

sizeof的第一个用法是错误的,而其他用法是正确的。

当使用 gcc 编译时,将显示以下错误消息:

main.c:5:9: error: expected expression before ‘int’

我的问题是为什么 C 标准不允许这种操作。 sizeof int会导致任何歧义吗?

7446 次浏览

The following could be ambiguous:

sizeof int * + 1

Is that (sizeof (int*)) + 1, or (sizeof(int)) * (+1)?

Obviously the C language could have introduced a rule to resolve the ambiguity, but I can imagine why it didn't bother. With the language as it stands, a type specifier never appears "naked" in an expression, and so there is no need for rules to resolve whether that second * is part of the type or an arithmetic operator.

The existing grammar does already resolve the potential ambiguity of sizeof (int *) + 1. It is (sizeof(int*))+1, not sizeof((int*)(+1)).

C++ has a somewhat similar issue to resolve with function-style cast syntax. You can write int(0) and you can write typedef int *intptr; intptr(0);, but you can't write int*(0). In that case, the resolution is that the "naked" type must be a simple type name, it can't just be any old type id that might have spaces in it, or trailing punctuation. Maybe sizeof could have been defined with the same restriction, I'm not certain.

From C99 Standard

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

In your case int is neither expression nor parenthesized name.

There are two ways to use the sizeof operator in C. The syntax is this:

C11 6.5.3 Unary operators
...
sizeof unary-expression
sizeof ( type-name )

Whenever you use a type as operand, you must have the parenthesis, by the syntax definition of the language. If you use sizeof on an expression, you don't need the parenthesis.

The C standard gives one such example of where you might want to use it on an expression:

sizeof array / sizeof array[0]

However, for the sake of consistency, and to avoid bugs related to operator precedence, I would personally advise to always use () no matter the situation.