在任何 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 不允许将升级大小的强制转换作为 size 的运算符。但是,这两种解释都符合优先规则。混淆来自*
运算符的歧义(是二进制运算符还是一元运算符?优先级表不是为了解决运算符歧义。毕竟,它们不是运算符符号优先级表。因此,运算符优先级规则本身是完整的。
3)a+b=c
导致语法错误,而不是语义错误
根据标准,a+b=c
是无效的C语法。如果 C 有一个基于优先级的解析器,它只会在语义级别被捕获。在 C 中,碰巧任何不是一元表达式的表达式都不能是 l 值。因此,这些语义上注定要失败的 LHS 表达式不需要在语法上适应。它对整个语言没有影响,优先级表不需要预测表达式将导致的错误的句法性/对称性。
例如,通常的优先级表表示sizeof
表达式和强制转换表达式具有相同的优先级。表格和标准都说它们从右到左关联。
当您查看时,这种简化很好,例如,*&foo
,这意味着与*(&foo)
相同。
它还可能向您暗示sizeof (int) 1
是合法的C++,并且它的含义与sizeof( (int) 1 )
相同。但这是不合法的,因为事实上sizeof( type-id )
在语法中是它自己的特殊事物。它的存在阻止了sizeof (int) 1
成为sizeof
表达式,其操作数是操作数为1
的强制转换表达式。
所以我认为你可以说C++语法中的"sizeof(type-id)"生产是通常的优先级/关联性表所说的例外。他们确实准确地描述了">一元表达的大小"生产。
这取决于"规则"是否正确。语言定义不讨论优先级,因此您在不同位置看到的优先级表可能会也可能不会反映语言定义的实际要求。
在有人找到反例之前,我将提出这个作为默认答案:
否,从不违反 C/C++ 优先级和关联性规则。