是C / C ++运算符优先级&相关性规则曾被违反?

时间:2012-11-25 13:53:56

标签: c++ syntax operators operator-precedence associativity

在任何C / C ++表达式中是否都违反了operator precedence & associativity rules
如果是这样,你能举个例子吗?

假设优先权和关联性规则的主张是:

  

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

编辑:背景

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

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

有些人声称?:运算符对其中间操作数的优先级高于对其其他操作数的优先级,因为a?b,c:d例如不会被解释为(a?b),(c:d)。但是,bc都不会占据?:作为内部操作数的位置。根据这个推理,a[b+c]应该被解释为(a[b)+(c]),这是荒谬的。

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

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

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

根据标准,

a+b=c是无效的C 语法。如果C有一个基于优先级的解析器,它只会在语义级别被捕获。在C中,任何不是一元表达式的表达式都不能是l值。因此,这些语义上注定的LHS表达式不需要在语法上适应。它对整个语言没有任何影响,优先级表不需要预测将由表达式产生的错误的语法/语义。

3 个答案:

答案 0 :(得分:6)

举一个例子,通常的优先级表说sizeof和强制转换表达式具有相同的优先级。表格和标准都表示它们从右向左关联。

当您查看*&foo时,这种简化就可以了,这意味着与*(&foo)相同。

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

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

答案 1 :(得分:3)

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

答案 2 :(得分:0)

在有人找到反例之前,我会将此作为默认答案:

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