C sizeof的消歧

C sizeof的消歧,c,C,在使用sizeof时,我总是将它括在括号中,因为在下面的第一种情况下,它更容易阅读,即使有时我可以省略它 sizeof unary-expression sizeof ( type-name ) 我的问题是,括号如何对编译器消除歧义?举个什么样的例子: sizeof char 对编译器来说是不明确的?在sizeof之后接受类型名将不允许在表达式中指定所有类型:指针类型(例如:sizeof char*10)将使解析复杂化,这目前非常简单。如果允许sizeof类型名,然后,sizeof char

在使用
sizeof
时,我总是将它括在括号中,因为在下面的第一种情况下,它更容易阅读,即使有时我可以省略它

sizeof unary-expression
sizeof ( type-name )
我的问题是,括号如何对编译器消除歧义?举个什么样的例子:

sizeof char

对编译器来说是不明确的?

sizeof
之后接受类型名将不允许在表达式中指定所有类型:指针类型(例如:
sizeof char*10
)将使解析复杂化,这目前非常简单。

如果允许
sizeof
类型名,然后,
sizeof char*+3
可以是:

  • (sizeof(char*)+3
    ,它是添加到
    3
    char*
    的大小;或
  • (sizeof(char))*(+3)
    ,它是
    字符的大小乘以
    +3
这两者都是有效的parsings,并且完全由标准定义(除了实现定义的指针大小)。因此,接受
sizeof
类型名称会产生语法或语义无法解决的歧义

前面的例子
如果允许
sizeof
类型名称,则
sizeof char[x]
可以是
(sizeof(char))[x]
(如果
x
是指针或数组,则该表达式有效;下标运算符接受
索引[array]
)或
sizeof(char[x])
(如果
x
是整数,则该表达式有效;它是
char
x
元素数组的大小)。此外,语法无法区分它们;两者都是有效的语法。语义规则可以根据
x
的类型来区分它们,但是您必须先进行语法分析,然后才能评估语义规则,并且编译器需要某种方法来撤销语法分析。

这是无效的,因为
char
是n不是一元表达式。[顺便说一句:如果不需要括号,我总是省略括号,例如
struct stuff*p=malloc(sizeof*p);
]@wildplasser这很明显,但问题是为什么选择这种语法。可能是因为类型可以是多个单词,而变量标识符不能。因为在wild west时代,可能涉及到宏。
sizeof(X)
将调用宏而不是内置运算符。我找不到我的K&R手册的原始版本,但我似乎记得他们的示例可能是这样做的。@jwdonahue您所有的三个版本?只有两个。
char*10
在C中不是有效的类型。
(char*)10
是一个有效的强制转换表达式,因此也是一元表达式。
char*10
是无效的C。我不明白为什么会提出它。
(char*)10
是有效的,
char*10
不是,这与sizeof无关。还有
sizeof const char*
vs
sizeof((const char*))
难题,是吗?关于char*+10的大小如何?:-)就语法而言,我现在看到它是不明确的,就实用的解析器而言,我打赌大多数解析器都是贪婪的,并且会很乐意尽可能长时间地构建类型名。SDCC的行为似乎就是这样,我必须检查gcc和其他开源解析器是否有类似的简单调整,看看如果所有更改都是“让我们放下括号”,它们会如何表现。我敢打赌,最初实现的C解析器也会贪婪地使用类型名。当然,解析器生成器会捕捉到歧义,手写生成器通常会悄悄地解决这些歧义。总之,这是一个任意的选择。是的,第二优先级的一元运算符是我没有看到的美中不足。非常感谢。