为什么表达式a = a + b - (b = a)在c ++中给出了一个序列点警告?

gja*_*ain 20 c++ operators operator-precedence sequence-points

以下是测试代码:

int main()
{
    int a = 3;
    int b = 4;
    a = a + b - (b = a); 

    cout << "a :" << a << " " << "b :" << b << "\n";    
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译它会发出以下警告:

> $ g++ -Wall -o test test.cpp test.cpp: In function ‘int main()’:
> test.cpp:11:21: warning: operation on ‘b’ may be undefined
> [-Wsequence-point]
Run Code Online (Sandbox Code Playgroud)

为什么操作不确定?

根据我的理解,首先(b = a)应该评估子表达式,因为()的优先级更高,因此设置b = a.然后,由于'+'和' - '具有相同的优先级,因此表达式将以左关联方式进行计算.因此,a + b应该接下来评估,最后(b = a)应该从中减去结果a + b.我看不到这里违反了任何序列点规则.

das*_*ght 20

评估的表达与完成其副作用之间存在差异.

b = a赋值表达式将提前减法的评价由于括号的更高的优先级.它将提供a评估结果的价值.b然而,将该值写入到下一个序列点之前可能无法完成,在这种情况下,该序列点是完整表达式的结束.因此,整体表达式的最终结果是未定义的,因为减法可以采用b赋值之前或之后的值.

  • 你的第二句话是错的.括号与评估顺序无关.例如,在表达式`f()+(g()+ h())`中,可以在6个可能的顺序中的任何一个中调用这三个函数. (3认同)

Die*_*Epp 8

在C++中,算术表达式中的子表达式没有时间排序.

a = x + y;
Run Code Online (Sandbox Code Playgroud)

x先进行计算,或y?编译器可以选择其中之一,也可以选择完全不同的东西.评价的顺序是一样的东西运算符优先级:运算符优先级被严格定义和评估的阶数仅定义为你的程序有序列点的粒度.

事实上,在某些体系结构,可以为发射评估代码两者xy在同一时间-例如,VLIW架构.