Why does i|= j|= k|= (j+= i) - - (k+++k) - - (i =+j) == 11?

后端 未结 4 1899
挽巷
挽巷 2020-12-22 14:33

I came across this code in a project I have started working on. The original developer is no longer available, and I can\'t make any sense of it:



        
4条回答
  •  醉酒成梦
    2020-12-22 15:30

    What is the =+ operator?

    That's two operators, one assignment operator, =, and one unary plus, +, which does nothing.

    Did you typo and mean the compund assignment operator +=?

    What is the +++ operator?

    Also two operators, one post-increment, ++, and one addition, +, (per the maximal munch rule, the longest valid token is chosen, it would become one addition and two unary plus if the shortest valid token were chosen).

    What is the - - operator?

    Again two operators, one subtraction, and one unary minus (negation).

    What is the |= operator?

    A compound assignment, bitwise-oring [or, in the case of boolean values, logical-oring] the left-hand-side value with the right-hand-side value and storing that in the left-hand-side variable.

    a |= b;
    

    is nearly equivalent to

    a = a | b;
    

    but the left-hand-side operand is evaluated only once, and the latter may need an explicit cast where the former doesn't.

    k = (j = (i = 0) + 2) + 1;
    return i|= j|= k|= (j+= i) - - (k+++k) - - (i =+j);
    

    It produces a value of 11. How does this work?

    The first line is equivalent to

    i = 0;
    j = i+2;
    k = j+1;
    

    The assignment (i = 0 for example) evaluates to the value stored (in i here).

    The next line is, with proper spacing, and implicit parentheses added

    return i |= (j |= (k |= (((j += i) - (-(k++ + k))) - (-(i = +j)))));
    
    • i |= stuff_1: i is evaluated (0), stuff_1 is evaluated, the bitwise or is taken, and the result stored in i. Since i is originally 0, that is equivalent to i = stuff_1.

    • j |= stuff_2: j is evaluated (2), stuff_2 is evaluated, the bitwise or is taken, and the result is stored in j.

    • k |= stuff_3: k is evaluated (3), then stuff_3, left-to-right.

      • (j += i) adds i to j, stores the sum in j and returns j's new value. Since i is 0, j doesn't change and the value is 2.
      • (k++ + k) takes the old value of k (3), increments k and adds k's new value (4), resulting in 7. That value is negated, and the negated value (-7) subtracted from 2, resulting in 2 - (-7) = 9.
      • (i = +j) stores the value of j (2) in i and the value of the expression is also 2. The value is negated (-2) and subtracted from the 9 we got from the previous operations, so stuff_3 evaluates to 11, with the side effects that

        • the stored value of i is now 2
        • the stored value of j is now 2 (didn't actually change, since i was 0 initially)
        • the stored value of k is now 4
      • the old value of k (3) is bitwise or'ed with 11, resulting in 11, that is stored in k, and 11 is the value of stuff_2, which is k |= stuff_3.
    • the old value of j (2) is bitwise or'ed with the value of stuff_2 (11), resulting in 11. The value is stored in j, and the value of stuff_1 (j |= stuff_2) is 11.

    • the old value of i (0) is bitwise or'ed with the value of stuff_1 (11), the result sored in i, and the value of i |= stuff_1 is 11. That value is then returned.

提交回复
热议问题