在C ++中,相等运算符的关联性是从左到右,如here和here所述,赋值操作的返回值是赋给给定变量的值。 (如图here,here,here和here所示(最后一个链接的第6.5.16节,第101-104页)。)
根据这些信息,这个:
double d = 5;
if (d == (d = 6))
cout << "but d was 5...!!!" << endl;
else
cout << "5!=6 :)" << endl;
应该打印"5!=6 :)"
,因为表达式(d == (d = 6))
等同于(5 == (6))
(这是假的),而是打印"but d was 5..."
。任何人都可以解释原因吗?
答案 0 :(得分:6)
标准的相关部分是:
[intro.execution] / 15 除非另有说明,否则对各个运算符的操作数和单个表达式的子表达式的评估都是无效的。在运算符的结果的值计算之前,对运算符的操作数的值计算进行排序。 如果对标量对象的副作用相对于同一标量对象的另一个副作用或使用相同标量对象的值的计算未被排序,并且它们不可能并发(1.10),则行为为未定义。强>
强调我的。您的程序显示未定义的行为,因为d
的修改(在比较的右侧)未使用d
的值计算(在其左侧)进行修改。相关性和优先权不会进入此。
答案 1 :(得分:4)
您将评估顺序与关联性混淆。
从左到右的关联性意味着
a == b == c
被解释为
(a == b) == c
这与a == b
等表达式中的术语评估顺序无关。编译器可以按任意顺序自由评估a
和b
。因此,在您的情况下,编译器可以先评估d
或先评估(d = 6)
。因此,您的计划可以评估为true
或false
,具体取决于首先评估运营商的哪一方。如果存在竞争条件(编译器也可以自由地并行评估它们),则结果将不同于一次运行。