【问题标题】:Why (and when) do I need to use parentheses after sizeof?为什么(以及何时)需要在 sizeof 之后使用括号?
【发布时间】:2011-05-05 08:42:35
【问题描述】:

以下编译失败:

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

sizeof.c:3: error: expected expression before ‘arr’

但是如果我把它改成

sizeof(arr);

一切都很好。为什么?

【问题讨论】:

  • sizeof 作为运算符在 ansi-c 中不可用
  • @Kostya:我的 K&R 副本(我拥有的对 C 语言的最早描述)非常遥远,我现在无法查看,但我 110% 确定它描述了 @987654323 @ 与今天的 C99 标准基本相同。 sizeof 在 1989 年 C 被 ANSI 标准化之前可用。
  • @Grim 您的说法“sizeof 作为运算符在 ansi-c 中不可用”是错误的。 C90 有第 3.3.3.4 节“sizeof 运算符”。在 C99 中,这移至第 6.5.3.4 节。

标签: c sizeof


【解决方案1】:

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

sizeof unary-expression
sizeof ( type-name )

由于您的代码中的arrtype-name,因此必须用括号括起来。

【讨论】:

  • +1 并且,只是为了强调 sizeof 是一个运算符:括号“属于”类型,而不是运算符。
  • @pmg:感谢您的澄清!是的,正如您所提到的,标准将sizeof 表示为运算符。
  • @pmg:我不认为括号“属于”什么很清楚。第二种形式的语法由三个标记和一个非终结符组成:sizeof ( type-name )。但是对于第一种形式,你可以写成sizeof(x),虽然它看起来像一个函数调用(如果sizeof不是关键字),它实际上是一个运算符应用于带括号的表达式。这就是你的想法吗?
  • 我的意思是 sizeof 在语法上是 sizeof <SOMETHING> 而不是函数,例如 printfprintf ( <SOMETHING> )。括号属于printf,但不属于sizeof。当sizeof 应用于带括号的类型名称时,我喜欢将其视为什么都没有——“返回”只是类型。
  • @pmg:你当然可以这样想,但我发现它具有误导性。与强制转换的唯一真正相似之处是它在括号中具有类型名称,这只是语法方便的巧合。我更喜欢将sizeof ( type-name ) 视为它自己的一种表达方式。 (标准将其称为运算符,但( type-name ) 并不是通常意义上的操作数。)
【解决方案2】:

这是指定语言的方式,类型名称必须在此处用括号括起来。

假设语法如下所示:

sizeof unary-expression sizeof <i>type-name</i>

现在,例如以下表达式将是模棱两可的:

sizeof int * + 0

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

必须在此处指定某些内容,并且要求将类型名称括起来是一种解决歧义的方法。

【讨论】:

    【解决方案3】:

    我想这是因为你有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));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-09
      • 2014-10-17
      • 2013-09-10
      • 1970-01-01
      • 1970-01-01
      • 2019-10-27
      相关资源
      最近更新 更多