Are there sequence points in the expression a^=b^=a^=b, or is it undefined?

前端 未结 4 1561
[愿得一人]
[愿得一人] 2020-12-11 15:15

The allegedly \"clever\" (but actually inefficient) way of swapping two integer variables, instead of using temporary storage, often involves this line:

int         


        
4条回答
  •  半阙折子戏
    2020-12-11 16:03

    The order of the evaluation of the ^= operators is well defined. What is not well defined is the order in which a and b are modified.

    a ^= b ^= a ^= b;
    

    is equivalent to

    a ^= (b ^= (a ^= b));
    

    An operator cannot be evaluated before its arguments are evaluated, so it is definitely going to execute a ^= b first.

    The reason to have this be undefined behavior is that, to give the compiler more flexibility in doing optimizations, it is allowed to modify the variable values in any order it chooses. It could choose to do this:

    int a1 = a ^ b;
    int b1 = b ^ a1;
    int a2 = a ^ b1;
    a = a1;
    a = a2;
    b = b1;
    

    or this:

    int a1 = a ^ b;
    int b1 = b ^ a1;
    a = a1;
    int a2 = a ^ b1;
    a = a2;
    b = b1;
    

    or even this:

    int a1 = a ^ b;
    int b1 = b ^ a1;
    int a2 = a ^ b1;
    a = a2;
    a = a1;
    b = b1;
    

    If the compiler could only choose one of those three ways to do things, this would just be "unspecified" behavior. However, the standard goes further and makes this be "undefined" behavior, which basically allows the compiler to assume that it can't even happen.

提交回复
热议问题