Why is x == (x = y) not the same as (x = y) == x?











up vote
14
down vote

favorite
2












Consider the following example:



class Quirky {
public static void main(String args) {
int x = 1;
int y = 3;

System.out.println(x == (x = y)); // false
x = 1; // reset
System.out.println((x = y) == x); // true
}
}


I'm not sure if there is an item in the Java Language Specification that dictates loading the previous value of a variable for comparison with the right side (x = y) which, by the order implied by brackets, should be calculated first.



Why does the first expression evaluate to false, but the second evaluate to true? I would have expected (x = y) to be evaluated first, and then it would compare x with itself (3) and return true.










share|improve this question




















  • 10




    The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
    – Louis Wasserman
    8 hours ago












  • @LouisWasserman The term evaluate is, in my opinion, inapplicable here because x does not need to be evaluated, it just loaded from memory.
    – John McClane
    8 hours ago








  • 3




    Evaluating the expression x = y is certainly relevant, and causes the side effect that x is set to the value of y.
    – Louis Wasserman
    8 hours ago










  • @LouisWasserman Sure. I knew that, and it was the main idea that lead me to quickReplaceAndCompare().
    – John McClane
    8 hours ago






  • 6




    Do yourself and your teammates a favor and don't mix state mutation into the same line as state examination. Doing so drastically reduces the readability of your code. (There are some cases where it's absolutely necessary because of atomicity requirements, but functions for those already exist and their purpose would be instantly recognized.)
    – jpmc26
    6 hours ago

















up vote
14
down vote

favorite
2












Consider the following example:



class Quirky {
public static void main(String args) {
int x = 1;
int y = 3;

System.out.println(x == (x = y)); // false
x = 1; // reset
System.out.println((x = y) == x); // true
}
}


I'm not sure if there is an item in the Java Language Specification that dictates loading the previous value of a variable for comparison with the right side (x = y) which, by the order implied by brackets, should be calculated first.



Why does the first expression evaluate to false, but the second evaluate to true? I would have expected (x = y) to be evaluated first, and then it would compare x with itself (3) and return true.










share|improve this question




















  • 10




    The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
    – Louis Wasserman
    8 hours ago












  • @LouisWasserman The term evaluate is, in my opinion, inapplicable here because x does not need to be evaluated, it just loaded from memory.
    – John McClane
    8 hours ago








  • 3




    Evaluating the expression x = y is certainly relevant, and causes the side effect that x is set to the value of y.
    – Louis Wasserman
    8 hours ago










  • @LouisWasserman Sure. I knew that, and it was the main idea that lead me to quickReplaceAndCompare().
    – John McClane
    8 hours ago






  • 6




    Do yourself and your teammates a favor and don't mix state mutation into the same line as state examination. Doing so drastically reduces the readability of your code. (There are some cases where it's absolutely necessary because of atomicity requirements, but functions for those already exist and their purpose would be instantly recognized.)
    – jpmc26
    6 hours ago















up vote
14
down vote

favorite
2









up vote
14
down vote

favorite
2






2





Consider the following example:



class Quirky {
public static void main(String args) {
int x = 1;
int y = 3;

System.out.println(x == (x = y)); // false
x = 1; // reset
System.out.println((x = y) == x); // true
}
}


I'm not sure if there is an item in the Java Language Specification that dictates loading the previous value of a variable for comparison with the right side (x = y) which, by the order implied by brackets, should be calculated first.



Why does the first expression evaluate to false, but the second evaluate to true? I would have expected (x = y) to be evaluated first, and then it would compare x with itself (3) and return true.










share|improve this question















Consider the following example:



class Quirky {
public static void main(String args) {
int x = 1;
int y = 3;

System.out.println(x == (x = y)); // false
x = 1; // reset
System.out.println((x = y) == x); // true
}
}


I'm not sure if there is an item in the Java Language Specification that dictates loading the previous value of a variable for comparison with the right side (x = y) which, by the order implied by brackets, should be calculated first.



Why does the first expression evaluate to false, but the second evaluate to true? I would have expected (x = y) to be evaluated first, and then it would compare x with itself (3) and return true.







java variable-assignment operator-precedence jls






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 57 mins ago









Boann

36.6k1287121




36.6k1287121










asked 8 hours ago









John McClane

447114




447114








  • 10




    The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
    – Louis Wasserman
    8 hours ago












  • @LouisWasserman The term evaluate is, in my opinion, inapplicable here because x does not need to be evaluated, it just loaded from memory.
    – John McClane
    8 hours ago








  • 3




    Evaluating the expression x = y is certainly relevant, and causes the side effect that x is set to the value of y.
    – Louis Wasserman
    8 hours ago










  • @LouisWasserman Sure. I knew that, and it was the main idea that lead me to quickReplaceAndCompare().
    – John McClane
    8 hours ago






  • 6




    Do yourself and your teammates a favor and don't mix state mutation into the same line as state examination. Doing so drastically reduces the readability of your code. (There are some cases where it's absolutely necessary because of atomicity requirements, but functions for those already exist and their purpose would be instantly recognized.)
    – jpmc26
    6 hours ago
















  • 10




    The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
    – Louis Wasserman
    8 hours ago












  • @LouisWasserman The term evaluate is, in my opinion, inapplicable here because x does not need to be evaluated, it just loaded from memory.
    – John McClane
    8 hours ago








  • 3




    Evaluating the expression x = y is certainly relevant, and causes the side effect that x is set to the value of y.
    – Louis Wasserman
    8 hours ago










  • @LouisWasserman Sure. I knew that, and it was the main idea that lead me to quickReplaceAndCompare().
    – John McClane
    8 hours ago






  • 6




    Do yourself and your teammates a favor and don't mix state mutation into the same line as state examination. Doing so drastically reduces the readability of your code. (There are some cases where it's absolutely necessary because of atomicity requirements, but functions for those already exist and their purpose would be instantly recognized.)
    – jpmc26
    6 hours ago










10




10




The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
– Louis Wasserman
8 hours ago






The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
– Louis Wasserman
8 hours ago














@LouisWasserman The term evaluate is, in my opinion, inapplicable here because x does not need to be evaluated, it just loaded from memory.
– John McClane
8 hours ago






@LouisWasserman The term evaluate is, in my opinion, inapplicable here because x does not need to be evaluated, it just loaded from memory.
– John McClane
8 hours ago






3




3




Evaluating the expression x = y is certainly relevant, and causes the side effect that x is set to the value of y.
– Louis Wasserman
8 hours ago




Evaluating the expression x = y is certainly relevant, and causes the side effect that x is set to the value of y.
– Louis Wasserman
8 hours ago












@LouisWasserman Sure. I knew that, and it was the main idea that lead me to quickReplaceAndCompare().
– John McClane
8 hours ago




@LouisWasserman Sure. I knew that, and it was the main idea that lead me to quickReplaceAndCompare().
– John McClane
8 hours ago




6




6




Do yourself and your teammates a favor and don't mix state mutation into the same line as state examination. Doing so drastically reduces the readability of your code. (There are some cases where it's absolutely necessary because of atomicity requirements, but functions for those already exist and their purpose would be instantly recognized.)
– jpmc26
6 hours ago






Do yourself and your teammates a favor and don't mix state mutation into the same line as state examination. Doing so drastically reduces the readability of your code. (There are some cases where it's absolutely necessary because of atomicity requirements, but functions for those already exist and their purpose would be instantly recognized.)
– jpmc26
6 hours ago














3 Answers
3






active

oldest

votes

















up vote
24
down vote













== is a binary equality operator.




The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.



Java 11 Specification > Evaluation Order > Evaluate Left-Hand Operand First







share|improve this answer



















  • 1




    @JohnMcClane "by the order implied by brackets" - the parentheses don't set any order, they form an operand for ==. Without the parentheses, neither of these expressions would be syntactically correct.
    – Andrew Tobilko
    6 hours ago




















up vote
14
down vote













As LouisWasserman sad, the expression is evaluated left to right. And java doesn't care what "evaluate" actually does, it only cares about generating a (non volatile, final) value to work with.



//the example values
x = 1;
y = 2;


So in quickReplaceAndCompare the following is done:



x == (x = y)
1 == (x = y)
1 == (x = 2) //assign 2 to x, returns 2
1 == 2
false


and in badReplaceAndCompare():



(x = y) == x
(x = 2) == x //assign 2 to x, returns 2
2 == x
2 == 2
true


note that badReplaceAndCompare() will always return true, because you are effectively comparing the assignment of a value to the variable it is assigned to, and a = b and b will, evaluated in that order, always be the same by definition.






share|improve this answer




























    up vote
    0
    down vote













    In the first test you're checking does 1 == 3.



    In the second test your checking does 3 == 3.



    (x = y) assigns the value and that value is tested. In the former example x = 1 first then x is assigned 3. Does 1 == 3?



    In the latter, x is assigned 3, and obviously it's still 3. Does 3 == 3?





    share





















      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53749841%2fwhy-is-x-x-y-not-the-same-as-x-y-x%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      24
      down vote













      == is a binary equality operator.




      The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.



      Java 11 Specification > Evaluation Order > Evaluate Left-Hand Operand First







      share|improve this answer



















      • 1




        @JohnMcClane "by the order implied by brackets" - the parentheses don't set any order, they form an operand for ==. Without the parentheses, neither of these expressions would be syntactically correct.
        – Andrew Tobilko
        6 hours ago

















      up vote
      24
      down vote













      == is a binary equality operator.




      The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.



      Java 11 Specification > Evaluation Order > Evaluate Left-Hand Operand First







      share|improve this answer



















      • 1




        @JohnMcClane "by the order implied by brackets" - the parentheses don't set any order, they form an operand for ==. Without the parentheses, neither of these expressions would be syntactically correct.
        – Andrew Tobilko
        6 hours ago















      up vote
      24
      down vote










      up vote
      24
      down vote









      == is a binary equality operator.




      The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.



      Java 11 Specification > Evaluation Order > Evaluate Left-Hand Operand First







      share|improve this answer














      == is a binary equality operator.




      The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.



      Java 11 Specification > Evaluation Order > Evaluate Left-Hand Operand First








      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 7 hours ago

























      answered 7 hours ago









      Andrew Tobilko

      24.3k84082




      24.3k84082








      • 1




        @JohnMcClane "by the order implied by brackets" - the parentheses don't set any order, they form an operand for ==. Without the parentheses, neither of these expressions would be syntactically correct.
        – Andrew Tobilko
        6 hours ago
















      • 1




        @JohnMcClane "by the order implied by brackets" - the parentheses don't set any order, they form an operand for ==. Without the parentheses, neither of these expressions would be syntactically correct.
        – Andrew Tobilko
        6 hours ago










      1




      1




      @JohnMcClane "by the order implied by brackets" - the parentheses don't set any order, they form an operand for ==. Without the parentheses, neither of these expressions would be syntactically correct.
      – Andrew Tobilko
      6 hours ago






      @JohnMcClane "by the order implied by brackets" - the parentheses don't set any order, they form an operand for ==. Without the parentheses, neither of these expressions would be syntactically correct.
      – Andrew Tobilko
      6 hours ago














      up vote
      14
      down vote













      As LouisWasserman sad, the expression is evaluated left to right. And java doesn't care what "evaluate" actually does, it only cares about generating a (non volatile, final) value to work with.



      //the example values
      x = 1;
      y = 2;


      So in quickReplaceAndCompare the following is done:



      x == (x = y)
      1 == (x = y)
      1 == (x = 2) //assign 2 to x, returns 2
      1 == 2
      false


      and in badReplaceAndCompare():



      (x = y) == x
      (x = 2) == x //assign 2 to x, returns 2
      2 == x
      2 == 2
      true


      note that badReplaceAndCompare() will always return true, because you are effectively comparing the assignment of a value to the variable it is assigned to, and a = b and b will, evaluated in that order, always be the same by definition.






      share|improve this answer

























        up vote
        14
        down vote













        As LouisWasserman sad, the expression is evaluated left to right. And java doesn't care what "evaluate" actually does, it only cares about generating a (non volatile, final) value to work with.



        //the example values
        x = 1;
        y = 2;


        So in quickReplaceAndCompare the following is done:



        x == (x = y)
        1 == (x = y)
        1 == (x = 2) //assign 2 to x, returns 2
        1 == 2
        false


        and in badReplaceAndCompare():



        (x = y) == x
        (x = 2) == x //assign 2 to x, returns 2
        2 == x
        2 == 2
        true


        note that badReplaceAndCompare() will always return true, because you are effectively comparing the assignment of a value to the variable it is assigned to, and a = b and b will, evaluated in that order, always be the same by definition.






        share|improve this answer























          up vote
          14
          down vote










          up vote
          14
          down vote









          As LouisWasserman sad, the expression is evaluated left to right. And java doesn't care what "evaluate" actually does, it only cares about generating a (non volatile, final) value to work with.



          //the example values
          x = 1;
          y = 2;


          So in quickReplaceAndCompare the following is done:



          x == (x = y)
          1 == (x = y)
          1 == (x = 2) //assign 2 to x, returns 2
          1 == 2
          false


          and in badReplaceAndCompare():



          (x = y) == x
          (x = 2) == x //assign 2 to x, returns 2
          2 == x
          2 == 2
          true


          note that badReplaceAndCompare() will always return true, because you are effectively comparing the assignment of a value to the variable it is assigned to, and a = b and b will, evaluated in that order, always be the same by definition.






          share|improve this answer












          As LouisWasserman sad, the expression is evaluated left to right. And java doesn't care what "evaluate" actually does, it only cares about generating a (non volatile, final) value to work with.



          //the example values
          x = 1;
          y = 2;


          So in quickReplaceAndCompare the following is done:



          x == (x = y)
          1 == (x = y)
          1 == (x = 2) //assign 2 to x, returns 2
          1 == 2
          false


          and in badReplaceAndCompare():



          (x = y) == x
          (x = 2) == x //assign 2 to x, returns 2
          2 == x
          2 == 2
          true


          note that badReplaceAndCompare() will always return true, because you are effectively comparing the assignment of a value to the variable it is assigned to, and a = b and b will, evaluated in that order, always be the same by definition.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 8 hours ago









          Poohl

          32319




          32319






















              up vote
              0
              down vote













              In the first test you're checking does 1 == 3.



              In the second test your checking does 3 == 3.



              (x = y) assigns the value and that value is tested. In the former example x = 1 first then x is assigned 3. Does 1 == 3?



              In the latter, x is assigned 3, and obviously it's still 3. Does 3 == 3?





              share

























                up vote
                0
                down vote













                In the first test you're checking does 1 == 3.



                In the second test your checking does 3 == 3.



                (x = y) assigns the value and that value is tested. In the former example x = 1 first then x is assigned 3. Does 1 == 3?



                In the latter, x is assigned 3, and obviously it's still 3. Does 3 == 3?





                share























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  In the first test you're checking does 1 == 3.



                  In the second test your checking does 3 == 3.



                  (x = y) assigns the value and that value is tested. In the former example x = 1 first then x is assigned 3. Does 1 == 3?



                  In the latter, x is assigned 3, and obviously it's still 3. Does 3 == 3?





                  share












                  In the first test you're checking does 1 == 3.



                  In the second test your checking does 3 == 3.



                  (x = y) assigns the value and that value is tested. In the former example x = 1 first then x is assigned 3. Does 1 == 3?



                  In the latter, x is assigned 3, and obviously it's still 3. Does 3 == 3?






                  share











                  share


                  share










                  answered 6 mins ago









                  Michael Puckett II

                  3,67641436




                  3,67641436






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53749841%2fwhy-is-x-x-y-not-the-same-as-x-y-x%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      flock() on closed filehandle LOCK_FILE at /usr/bin/apt-mirror

                      Mangá

                      Eduardo VII do Reino Unido