序列点 - Xor Swap on Array得到错误的结果

时间:2012-03-31 18:27:42

标签: c++ compiler-construction

我学会了使用Xor运算符来交换两个整数,例如:
int a = 21;
int b = 7;
a^=b^=a^=b;

我最终得到a = 7和b = 21。

我尝试像这样在数组上使用xor运算符:

int main()
{
    int a[] = {7,21};  
    a[0]^=a[1]^=a[0]^=a[1];

    cout << a[0] <<',' <<a[1];
    return 0;
}

输出 0,7
我在Xcode和g ++上编译代码,它们有同样的问题。

Xor swap on array适用于多行:

int main()
{
    int a[] = {7,21};  
    a[0]^=a[1];
    a[1]^=a[0];
    a[0]^=a[1];
    cout << a[0] <<',' <<a[1];
    return 0;
}

我的输出为 21,7

以下是我已经找到的信息:
- 问题在于序列点:Array + XOR swap fails
- 即使对于简单的整数,它们也可能对这种未定义的行为产生副作用:Why is this statement not working in java x ^= y ^= x ^= y;
- 关于xor swap的其他一些问题:Weird XOR swap behavior while zeroing out data

所以我应该避免使用xor swap,相反,使用temp交换可以保证正确的结果。

但我仍然不清楚a[0]^=a[1]^=a[0]^=a[1];发生了什么是序列点问题?

我无法弄清楚a[0]^=a[1]^=a[0]^=a[1];a^=b^=a^=b;之间编译器的不同之处是什么?


我怀疑是:
a[0]^=a[1]^=a[0]^=a[1];的编译器如何输出 0,7 。”

我知道这是序列指针问题,我可以理解为什么printf("%d,%d",i++, i++);未定义,因为某些编译器从左到右解析函数的参数,有些从右到左执行。

但我不知道a[0]^=a[1]^=a[0]^=a[1];上的问题是什么,它看起来与a^=b^=a^=b;相同。所以我想知道它如何与数组一起工作。所以我会更多地了解像“数组索引上的序列指针”

1 个答案:

答案 0 :(得分:7)

如果没有插入序列点,则不能多次修改变量,如果这样做,则未定义行为

a^=b^=a^=b;

尝试修改上述语句中ab的值会破坏此规则,最终会导致未定义的行为。
请注意,未定义的行为意味着任何行为都是可能的,您可以获得任何输出。

好读: