Why does XOR swap with integers trigger a warning?

若如初见. 提交于 2019-12-03 18:10:26

问题


I typed the following program:

#include <stdio.h>

int main(void) {
    int a = 3;
    int b = 42;

    printf("a = %d\nb = %d\n", a, b);

    printf("Exchanging values.\n");
    a ^= b ^= a ^= b;

    printf("a = %d\nb = %d\n", a, b);

    return 0;
}

and it's ok. When I try to compile it, I get this:

$ gcc test.c -o test -Wall -Wextra -ansi -pedantic-errors
test.c: In function ‘main’:
test.c:11: warning: operation on ‘a’ may be undefined

That's pretty much standard code, isn't it?

Why does it trigger a warning? As far as I know, bitwise XOR is implemented by default for int as long as you are using a standard implementation of C.

Thank you very much.


回答1:


Variable a is used as an lvalue twice in the expression.

Keep in mind that x ^= y is in fact a shortcut for x = x ^ y, and it means that the first operand is read, then written.

If you take the first operation out from the original expression, it is fine, see:

   b ^= a ^= b;    // OK
/*    2    1    */

Here, a is used twice and b is used three times. Since the assignment operator is right-to-left associative, first a ^= b is calculated, variable b is only read, variable a is read and then written, and the result (r1) is passed to the second operation. On the second operation, b ^= r1, b is read a second time (giving the same value as read previously) and then written. Note there is no way to interpret differently, no undefined behavior. In the above statement, a is read only once, b is read twice but both reads return the same value, and both a and b is written only once. It is ok.

When you add the third assignment to the left, it becomes a problem:

   a ^= b ^= a ^= b;    // NOT OK
/*    3    2    1    */

Now, a is read twice, once on operation 1 and once on operation 3, and also written on operation 1 and operation 3. What value should a return on operation 3, the original value or the value after operation 1 is processed?

The clever programmer may think that operation 1 is completely executed before operation 3 is processed, but this is not defined by the standard. It just happens to work with most compilers. On operation 3, the compiler may very well return the same value for a as it is returned for operation 1, causing the wrong result. This is undefined behavior.




回答2:


a ^= b ^= a ^= b; invokes Undefined Behaviour. You should use this:

a ^= b;
b ^= a;
a ^= b;


来源:https://stackoverflow.com/questions/5133428/why-does-xor-swap-with-integers-trigger-a-warning

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!