小知识:C/C++ 标准没有定义过任何的运算符优先级!

C/C++ 的优先级顺序表,以及运算法的结合性,是为了方便C/C++程序员理解语法规则,从标准指定的语言文法(表达式部分)中推导出来的。

实际上,标准指定的语言文法有一部分是无法通过优先级顺序表表示出来的。

  • 一个就是对 sizeof(unsigned)-1 的文法分析;
  • 另一个就是对 p1<p2 ? p1=NULL : p2=NULL,或者说 b ? p1 : p2 = nullptr 的文法分析。

标准指定的语言文法保证了语言不会出现歧义:

  1. sizeof 的运算数不能是类型转型:表达式 sizeof(unsigned)-1 无歧义地转译成 (sizeof(unsigned)) - 1 ,而非 sizeof((unsigned)-1)。
  2. 三元和赋值运算符的“相对优先级”在 C 与 C++ 不太一样,而且在 C 中会有一些实现与标准之间的差异:
    • C 标准指定的语言文法中,赋值不允许在三元运算符的右侧,故 e = a < d ? a++ : a = d 不能通过分析。
    • 许多 C 编译器使用修改的文法,其中 ?: 拥有高于 = 的优先级,这分析成 e = ( ((a < d) ? (a++) : a) = d )(之后编译失败,因为 C 中 ?: 决不是左值而 = 要求左值在左侧)。
    • C++ 标准指定的语言文法中, ?: 和 = 拥有相等的优先级并从右到左成组,故而 e = a < d ? a++ : a = d 分析为 e = ((a < d) ? (a++) : (a = d))。

附标准中的相关文法:

1. C89 - 3.3.3 Unary operators - Syntax

          unary-expression:
                  postfix-expression
                  ++  unary-expression
                  --  unary-expression
                  unary-operator cast-expression
                  sizeof  unary-expression
                  sizeof (  type-name )

          unary-operator: one of
                  &  *  +  -  ~  !

C89 - 3.3.4 Cast operators - Syntax

          cast-expression:
                  unary-expression
                  (  type-name )  cast-expression

其他 C/C++ 标准基本都是这样。
如 C18 的草案 N2176 以及 C++17 的草案 N4659:
N2176 - 6.5.3 Unary operators - Syntax
N4659 - 8.3 Unary expressions

2. C89 - 3.3.15 Conditional operator - Syntax

          conditional-expression:
                  logical-OR-expression
                  logical-OR-expression ?  expression :  conditional-expression

解释:
logical-OR-expression 是一个优先级最低到 || 的表达式。
expression 是一个优先级最低到 , 的表达式。
因为三元运算符右边,最低优先级允许递归的使用三元运算符,所以赋值不允许在三元条件运算符的右侧。

3. C++17 - 8.3 Unary expressions

N4659 - 8.3 Unary expressions
解释
assignment-expression 是一个优先级最低到 x= 的表达式。所以C++赋值允许在三元条件运算符的右侧。

附表达式文法顺序:#primary-expression -> #postfix-expression -> #unary-expression -> cast-expression -> multiplicative-expression -> additive-expression -> shift-expression -> relational-expression -> equality-expression -> AND-expression -> exclusive-OR-expression -> inclusive-OR-expression -> logical-AND-expression -> logical-OR-expression -> #conditional-expression -> $assignment-expression -> expression

posted @ 2018-08-08 10:09  xxyyttxx  阅读(270)  评论(0)    收藏  举报