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











up vote
16
down vote

favorite
3












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




















  • 15




    The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
    – Louis Wasserman
    11 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
    11 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
    11 hours ago






  • 9




    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
    8 hours ago








  • 2




    The real question is why you want to write code like this.
    – Broman
    3 hours ago















up vote
16
down vote

favorite
3












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




















  • 15




    The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
    – Louis Wasserman
    11 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
    11 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
    11 hours ago






  • 9




    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
    8 hours ago








  • 2




    The real question is why you want to write code like this.
    – Broman
    3 hours ago













up vote
16
down vote

favorite
3









up vote
16
down vote

favorite
3






3





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 3 hours ago









Boann

36.6k1287121




36.6k1287121










asked 11 hours ago









John McClane

457114




457114








  • 15




    The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
    – Louis Wasserman
    11 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
    11 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
    11 hours ago






  • 9




    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
    8 hours ago








  • 2




    The real question is why you want to write code like this.
    – Broman
    3 hours ago














  • 15




    The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
    – Louis Wasserman
    11 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
    11 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
    11 hours ago






  • 9




    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
    8 hours ago








  • 2




    The real question is why you want to write code like this.
    – Broman
    3 hours ago








15




15




The left hand side is always evaluated before the right hand side. The brackets don't make a difference to that.
– Louis Wasserman
11 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
11 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
11 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
11 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
11 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
11 hours ago




9




9




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
8 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
8 hours ago






2




2




The real question is why you want to write code like this.
– Broman
3 hours ago




The real question is why you want to write code like this.
– Broman
3 hours ago












3 Answers
3






active

oldest

votes

















up vote
27
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
    9 hours ago




















up vote
16
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|improve this answer





















      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
      27
      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
        9 hours ago

















      up vote
      27
      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
        9 hours ago















      up vote
      27
      down vote










      up vote
      27
      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 10 hours ago

























      answered 10 hours ago









      Andrew Tobilko

      24.4k84182




      24.4k84182








      • 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
        9 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
        9 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
      9 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
      9 hours ago














      up vote
      16
      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
        16
        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
          16
          down vote










          up vote
          16
          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 11 hours ago









          Poohl

          34319




          34319






















              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|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|improve this answer























                  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|improve this answer












                  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|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 2 hours ago









                  Michael Puckett II

                  3,67541436




                  3,67541436






























                      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

                      What visual should I use to simply compare current year value vs last year in Power BI desktop

                      How to ignore python UserWarning in pytest?

                      Alexandru Averescu