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











up vote
13
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 Java Language Specification that dictates loading 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 evaluates 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




















  • 9




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










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






  • 5




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

















up vote
13
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 Java Language Specification that dictates loading 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 evaluates 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




















  • 9




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










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






  • 5




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















up vote
13
down vote

favorite
2









up vote
13
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 Java Language Specification that dictates loading 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 evaluates 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 Java Language Specification that dictates loading 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 evaluates 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 2 hours ago









pushkin

3,859102550




3,859102550










asked 6 hours ago









John McClane

437113




437113








  • 9




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










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






  • 5




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
















  • 9




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










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






  • 5




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










9




9




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












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




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




5




5




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














2 Answers
2






active

oldest

votes

















up vote
20
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
    4 hours ago




















up vote
12
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





















    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-x-x-y-is-not-the-same-as-x-y-x%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    20
    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
      4 hours ago

















    up vote
    20
    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
      4 hours ago















    up vote
    20
    down vote










    up vote
    20
    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 5 hours ago

























    answered 5 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
      4 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
      4 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
    4 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
    4 hours ago














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










        up vote
        12
        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 5 hours ago









        Poohl

        30319




        30319






























            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-x-x-y-is-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