序列点和评估顺序(预增量)

iam*_*nka 0 c++ language-lawyer c++11

我的一些同事今天进行了辩论,我想澄清一下.它是关于表达式中的评估顺序和序列点.标准中明确指出,C/C++在表达式中没有从左到右的评估,这与Java之类的语言不同,后者保证具有从左到右的顺序.因此,在下面的表达式中,在评估最右边的操作数(C)之前,对二进制操作中最左边的操作数(B)的求值进行排序:

A = B B_OP C
Run Code Online (Sandbox Code Playgroud)

根据序列前序列(Undefined Behavior)和Bjarne的TCPPL 3rd ed 下的CPPReference,下面的表达式是UB

x = x++ + 1;
Run Code Online (Sandbox Code Playgroud)

它可以被解释为像BUT这样的编译器,据说下面的表达式在C++ 11中显然是一个明确定义的行为

x = ++x + 1;
Run Code Online (Sandbox Code Playgroud)

那么,如果上面的表达式定义得很清楚,那么"命运"是什么呢?

array[x] = ++x;
Run Code Online (Sandbox Code Playgroud)

似乎没有定义后增量和后减量的评估,但定义了预增量和预减量.

注意:这不用于实际代码中.Clang 3.4和GCC 4.8明确警告了增量前后序列点.

Mik*_*our 5

让我们看看标准中有关排序的内容:

C++ 11 5.17/1:在右和左操作数的值计算之后,以及赋值表达式的值计算之前,对赋值进行排序.

因此,操作数的计算array[x],并++x相对于彼此测序.两者都使用值x,并且一个修改它,给出未定义的行为.

(第二个例子的不同之处在于不使用x左操作数中的 ;它仍然是左值).