1

是否在任何 C/C++ 表达式中违反了运算符优先级和关联性规则?
如果是这样,你能举个例子吗?

假设优先级和关联性规则的声明是:

每个运算符都有一个给定的优先级,每个优先级都有一个给定的关联性。如果两个运算符在它们期望操作数的地方看到一个子表达式,则它属于具有更高优先级的那个。联系被关联性打破。

编辑:背景

该标准将 C/C++ 表达式定义为 CFG,它比基于优先级的解析器灵活得多。例如,可以给二元运算符提供不对称的“优先级”,这会导致任何优先级表不正确。然而,在我看来,语法的设计被限制为支持简单的优先规则。以下是我遇到的一些所谓的“反例”:

1) a?b,c:d不被解释为(a?b),(c:d)

一些人声称,?:运算符对其中间操作数的优先级与对其其他操作数的优先级不同a?b,c:d,例如,因为 不被解释为(a?b),(c:d)。但是,既不b也不c占据它似乎?:作为其内部操作数的位置。按此推理a[b+c]应解释为(a[b)+(c]),这是可笑的。

2) sizeof(int)*a被解释为(sizeof(int))*a而不是sizeof((int)(*a))

...因为 C 不允许将带括号的强制转换作为 sizeof 的运算符。但是,这两种解释都符合优先规则。混淆来自*运算符的歧义(是二元运算符还是一元运算符?)。优先表并不意味着解决运算符的歧义。毕竟,它们不是运算符符号优先表。所以运算符优先级规则本身是完整的。

3) a+b=c导致语法错误,而不是语义错误

a+b=c,根据标准,是无效的 C语法。如果 C 有一个基于优先级的解析器,它只会在语义级别被捕获。在 C 中,碰巧任何不是一元表达式的表达式都不能是左值的。因此,这些语义上注定要失败的 LHS 表达式不需要在语法上进行调整。它对整个语言没有影响,优先表不必用于预测表达式将导致的错误的句法/语义。

4

3 回答 3

6

举个例子,通常的优先级表表明sizeof和 cast 表达式具有相同的优先级。表格和标准都说它们是从右到左关联的。

当您查看时,这种简化很好,例如*&foo,这意味着与 相同*(&foo)

它还可能向您建议这sizeof (int) 1是合法的 C++,并且它的含义与sizeof( (int) 1 ). 但它是不合法的,因为实际上sizeof( type-id )它在语法中是一个特殊的东西。它的存在阻止sizeof (int) 1了一个sizeof表达式,其操作数是一个其操作数是 的强制转换表达式1

所以我认为你可以说 C++ 语法中的“sizeof ( type-id )”产生是通常的优先级/关联性表所说的一个例外。他们确实准确地描述了“一元表达式的大小”产生。

于 2012-11-25T14:37:58.093 回答
3

这取决于“规则”是否正确。语言定义不讨论优先级,因此您在各个地方看到的优先级表可能反映也可能不反映语言定义实际需要的内容。

于 2012-11-25T13:58:29.733 回答
0

在有人能找到反例之前,我将把它作为默认答案提出:

不,永远不会违反 C/C++ 优先级和关联性规则。

于 2012-11-25T19:08:57.180 回答