• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Junilu Lacar
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Knute Snortum
  • Devaka Cooray
  • Tim Cooke
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Ron McLeod
  • Carey Brown
Bartenders:
  • Paweł Baczyński
  • Piet Souris
  • Vijitha Kumara

Operator Precedence and Infinite Loops

 
Greenhorn
Posts: 7
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So I'm going over the OCA book, and in Chapter 2, review question 9, the code is as follows:


The answer appears to be an infinite loop, because gets assigned the same value every time, and I don't see how:
If the i is first read and assigned (0), then incremented (1), then at the end of line 2, i = 1.
If the i is first incremented (1), then assigned (1), then at the end of line 2, i is still = 1.

So what am I not seeing?

Thanks.
 
author & internet detective
Posts: 39587
781
Eclipse IDE VI Editor Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The compiler things about it like this:
  • Ok. So first I execute i++.
  • I'll remember that the original value is 0.
  • Then I'll increment i to 1.
  • Ah, I see you want the result of my statement set to i. No problem, that's the original value you told me to remember.  (zero)
  • Now i is set to 0
  •  
    Roman Vilensky
    Greenhorn
    Posts: 7
    Eclipse IDE Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Jeanne Boyarsky wrote:The compiler things about it like this:

  • Ok. So first I execute i++.
  • I'll remember that the original value is 0.
  • Then I'll increment i to 1.
  • Ah, I see you want the result of my statement set to i. No problem, that's the original value you told me to remember.  (zero)
  • Now i is set to 0


  • Oh,

    So that's what I was missing - the "remember" part.
    Instead of my: assign -> increment, it's actually remember-> increment -> assign remembered.

    Thank you!.
     
    Marshal
    Posts: 66192
    250
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Yes, i++ has two values, the value of i (increment) which you cannot see until later, and the old value (remember) which you see now as the value of the whole expression.Many people are surprised when it prints 123.
     
    Roman Vilensky
    Greenhorn
    Posts: 7
    Eclipse IDE Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:Yes, i++ has two values, the value of i (increment) which you cannot see until later, and the old value (remember) which you see now as the value of the whole expression.Many people are surprised when it prints 123.



    Right. I was mistaken about the order in which these happen. I thought it was assign old value, then increment, but it is the other way around.
     
    Marshal
    Posts: 7267
    492
    Mac OS X VI Editor BSD Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Roman Vilensky wrote:Right. I was mistaken about the order in which these happen. I thought it was assign old value, then increment, but it is the other way around.


    Unclear whether you understood.

    Not sure how that is exactly implemented, but I think always that way.
     
    Campbell Ritchie
    Marshal
    Posts: 66192
    250
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I don't know that there is an order for those things to happen. I don't remember the JLS (=Java® Language Specification) sayint there is an order, but it does say that the value of a postfix expression is the same as the old value of the variable involved.

    That JLS link wrote:The value of the postfix increment expression is the value of the variable before the new value is stored.

    The same applies to i--, by the way.
    You can try using javap to investigate further; the actual bytecode output might change from implementation to implementation.It does appear the expression's value is loaded (iload_1) before/after the iinc 1, 1 depending on the position of the ++ in line 6, but that may be an implementation detail.
     
    Greenhorn
    Posts: 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator




    Remove "i=" for finite loop.
     
    Saloon Keeper
    Posts: 21254
    137
    Android Eclipse IDE Tomcat Server Redhat Java Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Roman Vilensky wrote:
    Right. I was mistaken about the order in which these happen. I thought it was assign old value, then increment, but it is the other way around.



    That's the difference between post-increment (i++) and pre-increment (++i), as Liutauras pointed out. I'm repeating him, just using the formal names of those operators.

    pre/post increment/decrement have a fairly high operator precedence - as is common with unary operators. Assignment has a very low operator precedence. If it didn't a lot of equations wouldn't, er, "equate".
     
    Liutauras Vilda
    Marshal
    Posts: 7267
    492
    Mac OS X VI Editor BSD Linux
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Liutauras Vilda wrote:


    Somebody pointed out for me correctly... Treat that code example as either there is line 4 or 5, but not both. Because in a case of both lines, line 5 result would have been different.
     
    Roman Vilensky
    Greenhorn
    Posts: 7
    Eclipse IDE Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Liutauras Vilda wrote:

    Roman Vilensky wrote:Right. I was mistaken about the order in which these happen. I thought it was assign old value, then increment, but it is the other way around.


    Unclear whether you understood.

    Not sure how that is exactly implemented, but I think always that way.



    That's a good point, but in my original example it's not i = n++, it's i = i++.
    What I was assuming, is that i gets assigned the old value, but then gets incremented anyway.
    What Jeanne Boyarsky pointed out, is that it's a three step process, not a two step process as I assumed. So, not assign old value then increment, but save old value, increment, assign old value.
     
    Liutauras Vilda
    Marshal
    Posts: 7267
    492
    Mac OS X VI Editor BSD Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Got it what you mean, all good
     
    Marshal
    Posts: 14347
    237
    Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Roman Vilensky wrote:it's a three step process, not a two step process as I assumed. So, not assign old value then increment, but save old value, increment, assign old value.


    In this particular case, that reasoning might help you reconcile what's happening but it's not really accurate. In fact, this might even mislead you in evaluating what happens in more complicated situations that involve these operations.

    The real reason is more along the lines of what Tim said about operator precedence.

    Take this for example:

    Which value of i is being remembered here? How does the "remembering" line of reasoning explain why the result of this is i being assigned 2?

    What really happens is that because the assignment operation has very low precedence as Tim mentioned, it occurs after the expression on the right hand side has been fully evaluated. When fully evaluated, the expression (i++) has a value of the current value of i which is then assigned to i. So, even though i is still incremented as part of the process of evaluating i++, the assignment made after the expression evaluation basically supersedes the effect of the post-increment operator on i.

    Study the following to get a better idea of the order of evaluation of the above statement (you can copy/paste that into JShell):

     
    Liutauras Vilda
    Marshal
    Posts: 7267
    492
    Mac OS X VI Editor BSD Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I'll re-iterate this too in the way I did few times in the past. That is probably technically not very precise what is going on or the exact rules aren't spelt out exactly as they are in JLS, but it helps (at least to me) to arrive at correct result always, regardless how complicated the expression is.

    So, two rules for a start once again (same applies to decrement):
    i++ (place into expression and only then increment)
    ++i (increment and only then place into expression)


    Taking Junilu's example:
    1. our initial value of i is 0.
    2. let's start, we have i++ first, so we place value into expression and only then increment, so our current expression looks like:
    i = 0 +

    3. Since we placed i value into expression first (as per two rules above), now we still owe to increment i, so let's do that. i now is 1. And again, we have i++, which means, place current value into expression and only then increment. So our expression now looks:
    i = 0 + 1 *

    4. So, since we placed value into expression first in step 3, we still owe to increment i, so let's do that. i now is 2. Yet again we have i++, which means, we place current value into expression and only then increment. So our expresion now looks:
    i = 0 + 1 * 2; (<-- and it gets freezed/locked, because we revelead all unknown values, this expression can't be affected by any other operation if we still owe, read step 5 down below).

    5. Since we placed value into expression first, we still owe to increment i, so now i technically i should be 3, and maybe it is for a fraction of a second, I don't know, but here my last rule kicks in, if the post-increment/decrement is part of expression (on the same single line), the last post increment/decrement operation has no effect to the expression which we just freezed/locked, because all the values to compute what needs to be assigned is known already).

    So we are left just to calculate result from step four. Which is 2 of course. I find this way very difficult to get wrong using those simple 3 rules:
  • i++ or i-- (place current value into expression and only then increment/decrement)
  • ++i or --i (increment/decrement current value and only then place into expression)
  • if the last variable you see in the expression is related to post-increment/decrement, after placing its current value into expression, the increment/decrement operation which should be happening afterwards has no effect for the expression's final result

  • And that's all.

    If you are writing a scientific article, most likely that is not enough to know, and in fact might be even incorrect (and sort of unprofessional), but from the practice point of view, that simply just works to think that way.
     
    Liutauras Vilda
    Marshal
    Posts: 7267
    492
    Mac OS X VI Editor BSD Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Earlier, I wrote:if the last variable you see in the expression is related to post-increment/decrement, after placing its current value into expression, the increment/decrement operation which should be happening afterwards has no effect for the expression's final result


    And if you look once again to this rule (again, the rule the way I interpret, not JLS), your initial example:
    gets super simple too, since i++ which is the only one is also the last one in the expression, so you get:


    And when you get a moment "Ah, I know now, that's easy!", there is always... something else... until...?

    @OP
    Challenge for you, what would be printed out? And why?
     
    straws are for suckers. tiny ads are for attractive people.
    Java file APIs (DOC, XLS, PDF, and many more)
    https://products.aspose.com/total/java
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!