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

blu*_*ift 74 c sizeof

以下无法编译:

typedef int arr[10];
int main(void) {
    return sizeof arr;
}

sizeof.c:3: error: expected expression before ‘arr’
Run Code Online (Sandbox Code Playgroud)

但如果我改成它

sizeof(arr);
Run Code Online (Sandbox Code Playgroud)

一切都好.为什么?

Ise*_*ria 111

根据6.5.3,有两种形式sizeof如下:

sizeof unary-expression
sizeof ( type-name )
Run Code Online (Sandbox Code Playgroud)

因为arr在你的代码中是a type-name,所以必须用括号括起来.

  • +1和,只是为了强化`sizeof`是一个运算符:括号"属于"类型,而不是运算符. (14认同)
  • @pmg:我不认为括号"属于"是什么.第二种形式的语法由三个令牌和一个非终端组成:`sizeof(type-name)`.但是对于第一种形式,你*可以*编写,例如,`sizeof(x)`,虽然它看起来像一个函数调用(如果`sizeof`不是一个关键字),它实际上是一个应用于括号的运算符表达.那是你的想法吗? (4认同)
  • 我的意思是`sizeof`在语法上是`sizeof <SOMETHING>`而不是函数,例如,`printf`是`printf(<SOMETHING>)`.括号属于`printf`但不属于`sizeof`.当`sizeof`应用于带括号的类型名称时,我喜欢将其视为无任何投射 - 只返回类型. (3认同)
  • @pmg:你当然可以这样想,但我觉得它有误导性.与演员表的唯一真正相似之处在于它在括号中有一个类型名称,这只是句法方便的巧合.我更喜欢把`sizeof(type-name)`看作是它自己的表达式.(标准称它为运算符,但`(类型名称)`在通常意义上并不是真正的操作数.) (2认同)

maf*_*fso 40

这是指定语言的方式,类型名称必须在此处加括号.

假设语法看起来像这样:

sizeof unary-expression sizeof type-name

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

sizeof int * + 0
Run Code Online (Sandbox Code Playgroud)

它可以是sizeof(int *) + 0sizeof(int) * +0.对于一元表达式不会出现这种歧义,因为附加到表达式的星号不是表达式(但对于某些类型名称,附加一个,也是类型名称).

这里必须指定一些东西,并且要求括号的类型名称是解决歧义的一种方法.