我仍然无法清楚地了解表达式x ^= y ^= x ^= y;
在C ++ 11中有效(正如他们在thread中所说的那样)或者它会导致未定义的行为?
该链接给出的理由似乎令人信服,但clang抛出warning:
警告:未经测试的修改和访问'x'[-Wunsequenced]
此外,如果两个版本:
x ^= y ^= x ^= y; // (1)
x = x ^ (y = y ^ (x = (x ^ y))); // (2)
被认为是等效的(并且在C ++ 11中定义明确),为什么它会给出不同的结果(first,second)?
此外,应该注意的是,gcc仅在第二版代码上提供warning序列点。
答案 0 :(得分:11)
赋值运算符(=)和复合赋值运算符all 小组从右到左。 [..]
除E1 op = E2
之外,E1 = E1 op E2
形式的表达式的行为等同于E1
只评估一次。
因此,您的代码等同于
x = x ^ (y ^= (x ^= y)));
... x在x = x ...
中仅评估一次。
不幸的是,对于xor,操作数的评估是不确定的。即
除非另有说明,否则评估各个运营商的操作数 并且个别表达的子表达式没有被排除。
适用。但现在我们遇到了一个问题:
x = x ^ (y ^= (x ^= y)));
// * ******
// | |
// | Side effect
// Value computation
值计算(对于最左边的两个x
的{{1}}的单数评价中暗示)和副作用彼此不相关,因此我们诱导UB:
如果标量对象的副作用相对于其中任何一个都没有排序 对同一标量对象或值计算的另一个副作用 使用相同标量对象的值,行为未定义。