C 为什么(以及何时)我需要在sizeof之后使用括号?

C 为什么(以及何时)我需要在sizeof之后使用括号?,c,sizeof,C,Sizeof,以下文件未能编译: 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是一个类型名,

以下文件未能编译:

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
是一个
类型名
,因此必须用括号括起来。

这就是指定语言的方式,类型名必须用括号括起来

假设语法如下所示:

一元表达式的大小
sizeof type name

现在,例如,以下表达式将是不明确的:

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作为运算符在ansi中不可用-c@Kostya:我的K&R副本(我拥有的C语言的最早描述)非常遥远,我现在无法检查它,但我110%确信它描述的
sizeof
与C99标准今天的描述基本相同
sizeof
在1989年C被ANSI标准化之前就可用了。@您的陈述“sizeof作为运算符在ANSI-C中不可用”是错误的。C90有第3.3.3.4节“sizeof运算符”。在C99中,这移到了第6.5.3.4.+1节,只是为了强调
sizeof
是一个运算符:括号“属于”类型,而不是运算符。@pmg:谢谢澄清!是的,正如您所提到的,该标准将
sizeof
表示为运算符。@pmg:我不认为括号“属于”什么很清楚。第二种形式的语法由三个标记和一个非终端组成:
sizeof(type name)
。但对于第一种形式,您可以编写,例如,
sizeof(x)
,尽管它看起来像一个函数调用(如果
sizeof
不是关键字),但它实际上是一个应用于括号表达式的运算符。这就是你所想的吗?我的意思是,
sizeof
在语法上是
sizeof
,而不是函数,例如,一个
printf
,它是
printf()
。括号属于
printf
,但不属于
sizeof
。当
sizeof
应用于带括号的类型名时,我喜欢将其视为一种无条件转换--“返回”只是类型。@pmg:您当然可以这样想,但我发现它会误导您。与强制转换唯一的相似之处在于它在括号中有一个类型名,这只是语法方便的巧合。我更愿意把
sizeof(type name)
看作它自己的一种表达式。(标准称之为运算符,但
(类型名)
实际上不是通常意义上的操作数。)