以下内容无法编译:
typedef int arr[10];
int main(void) {
return sizeof arr;
}
sizeof.c:3: error: expected expression before ‘arr’
但是如果我将它更改为
sizeof(arr);
一切都好,为什么呢?
根据6.5.3,sizeof
有以下两种形式:
sizeof unary-expression
sizeof ( type-name )
由于你代码中的 arr
是一个 type-name
,因此它必须加上括号。
sizeof
是一个运算符:括号应该与类型一起使用,而不是与运算符一起使用。 - pmgsizeof(x)
,虽然它看起来像是一个函数调用(如果'sizeof'不是关键字),但实际上它是应用于带括号表达式的运算符。这是你想要的吗? - Keith Thompsonsizeof
的语法是 sizeof <SOMETHING>
,而不像函数,例如 printf
是 printf ( <SOMETHING> )
。括号属于 printf
,但不属于 sizeof
。当 sizeof
应用于括号中的类型名称时,我认为它类似于对无内容进行转换,仅“返回”类型。 - pmgsizeof (type-name)
视为一种独立的表达式。(标准将其称为运算符,但(type-name)
并不是通常意义下的操作数。) - Keith Thompsonsizeof("abcdefghij"[0])
,而不是 sizeof(0)["abcdefghij"]
。参见 https://dev59.com/83RC5IYBdhLWcg3wMd9S/ - jcsahnwaldt Reinstate Monica这就是语言的规定,这里必须给类型名称加上括号。
假设语法看起来像这样:
sizeof 一元表达式
sizeof (类型名称)
现在,例如以下表达式将是模糊不清的:
sizeof int * + 0
这可能是 sizeof(int *) + 0
或者是 sizeof(int) * +0
。对于一元表达式来说不会出现歧义,因为在表达式后面添加一个星号不是一个表达式(但对于某些类型名来说,再次添加一个星号又成为了一个类型名)。
这里必须指定一些内容,要求类型名必须加括号就是解决这种歧义的方法。
我认为这是因为你使用了typedef
。如果你将其移除,它应该可以编译。
维基百科的例子:
/* the following code fragment illustrates the use of sizeof
* with variables and expressions (no parentheses needed),
* and with type names (parentheses needed)
*/
char c;
printf("%zu,%zu\n", sizeof c, sizeof (int));
sizeof
的描述是基本相同的。自1989年ANSI标准化C语言之前,sizeof
就已经存在了。 - pmg