【发布时间】:2012-11-25 13:53:56
【问题描述】:
operator precedence & associativity rules 是否曾在任何 C/C++ 表达式中被违反?
如果有,能举个例子吗?
假设优先级和关联性规则的声明是:
每个运算符都有一个给定的优先级,每个优先级都有一个给定的关联性。如果两个运算符在它们期望操作数的地方看到一个子表达式,则它属于具有更高优先级的那个。联系被关联性打破了。
编辑:背景
该标准将 C/C++ 表达式定义为 CFG,它比基于优先级的解析器灵活得多。例如,可以给二元运算符提供不对称的“优先级”,这会导致 any 优先级表不正确。然而,在我看来,语法的设计被限制为支持简单的优先规则。以下是我遇到的一些所谓的“反例”:
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 的运算符。但是,这两种解释都符合优先规则。混淆来自* 运算符的歧义(是二元运算符还是一元运算符?)。优先表并不意味着解决运算符的歧义。毕竟,它们不是运算符-符号-优先表。所以 operator 优先规则本身是完整的。
3) a+b=c 导致语法错误,而不是语义错误
a+b=c,根据标准,是无效的 C 语法。如果 C 有一个基于优先级的解析器,它只会在 语义 级别被捕获。在 C 中,碰巧任何不是 unary-expression 的表达式都不能是左值的。因此,这些语义上注定要失败的 LHS 表达式不需要在语法上进行调整。它对整个语言没有影响,优先表不必用于预测表达式将导致的错误的句法/语义。
【问题讨论】:
-
你为什么要问?这些规则应该是“具体的”,但总是存在编译器错误的可能性(尽管是远程的)。但更多情况下,这些规则只是被用户误解了。
-
@HotLicks - “优先规则”也可能是错误的。语言定义没有讨论优先级。
-
“问题是关于语言,而不是解析器”是什么意思?语法解析器要么正确反映语言规范,要么不符合标准。因此,任何符合语法的解析器都与该语言一致。如果不是符合标准的解析器,什么是“ 解析器”?
-
@HotLicks 我同意。查看添加的背景。
-
@SteveJessop 语法解析器。 C 采用了一些语法快捷方式,这些快捷方式会影响语法而不影响语言。我删除了那句话,并添加了示例 3。
标签: c++ syntax operators operator-precedence associativity