I did not know that was legal

Discussion in 'Java' started by Roedy Green, Feb 24, 2006.

  1. Roedy Green

    Roedy Green Guest

    I have using Intellij. One thing it often does in make suggestions on
    how to improve your code. One it made, I thought was illegal till I
    tried it out.


    If you have code like this:

    case 1:
    int x = expression;
    break;
    case 2:
    x = expression;
    break;

    that is LEGAL even though program flow does not flow through the
    definition. You DON'T have to promote x out of the switch. You can
    think of it that it works AS IF you always fell through each case. The
    key to this mystery is understanding that local variables are not
    actually allocated where you define them. They all get allocated at
    once when you enter the method by reserving N stack slots, where they
    effectively became extra dummy parameters to your method.

    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Java custom programming, consulting and coaching.
     
    Roedy Green, Feb 24, 2006
    #1
    1. Advertising

  2. Roedy Green

    Guest

    In article <>, Roedy Green wrote:
    > I have using Intellij. One thing it often does in make suggestions on
    > how to improve your code. One it made, I thought was illegal till I
    > tried it out.
    >
    >
    > If you have code like this:
    >
    > case 1:
    > int x = expression;
    > break;
    > case 2:
    > x = expression;
    > break;
    >
    > that is LEGAL


    It might be legal, but does it really *improve* your code??

    Paul
     
    , Feb 24, 2006
    #2
    1. Advertising

  3. Roedy Green wrote:
    >
    > If you have code like this:
    >
    > case 1:
    > int x = expression;
    > break;
    > case 2:
    > x = expression;
    > break;
    >
    > that is LEGAL even though program flow does not flow through the
    > definition. You DON'T have to promote x out of the switch.

    A way to write it a little less irritating is:

    switch (...) {
    int x;
    case 1:
    x = expression;
    break;
    case 2:
    x = expression;
    break;
    }

    --
    "Thomas:Fritsch$ops:de".replace(':','.').replace('$','@')
     
    Thomas Fritsch, Feb 24, 2006
    #3
  4. Roedy Green

    Timo Stamm Guest

    Roedy Green schrieb:
    > The
    > key to this mystery is understanding that local variables are not
    > actually allocated where you define them. They all get allocated at
    > once when you enter the method


    It's not per method, but per block:

    {
    int x = 0;
    }
    x = 3; // unknown variable



    Timo
     
    Timo Stamm, Feb 24, 2006
    #4
  5. Roedy Green

    Daniel Dyer Guest

    On Fri, 24 Feb 2006 11:51:03 -0000, Roedy Green
    <> wrote:

    > I have using Intellij. One thing it often does in make suggestions on
    > how to improve your code. One it made, I thought was illegal till I
    > tried it out.
    >
    >
    > If you have code like this:
    >
    > case 1:
    > int x = expression;
    > break;
    > case 2:
    > x = expression;
    > break;
    >
    > that is LEGAL even though program flow does not flow through the
    > definition. You DON'T have to promote x out of the switch. You can
    > think of it that it works AS IF you always fell through each case. The
    > key to this mystery is understanding that local variables are not
    > actually allocated where you define them. They all get allocated at
    > once when you enter the method by reserving N stack slots, where they
    > effectively became extra dummy parameters to your method.


    It doesn't work if you put curly brackets around your case code like this,
    which is how I prefer to write my switches:

    case 1:
    {
    int x = expression;
    break;
    }
    case 2:
    {
    x = expression;
    break;
    }


    Dan.


    --
    Daniel Dyer
    http://www.dandyer.co.uk
     
    Daniel Dyer, Feb 24, 2006
    #5
  6. Roedy Green

    Roedy Green Guest

    On 24 Feb 2006 12:06:58 GMT, wrote, quoted or
    indirectly quoted someone who said :

    >It might be legal, but does it really *improve* your code??


    That is debatable, but in does have the effect of narrowing the scope
    of a variable, which is general is a good thing. I mention this not
    to advocate strange looking code, but so that you will believe you
    eyes when you see it.
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Java custom programming, consulting and coaching.
     
    Roedy Green, Feb 24, 2006
    #6
  7. Daniel Dyer wrote:
    > On Fri, 24 Feb 2006 11:51:03 -0000, Roedy Green
    > <> wrote:
    >
    >> I have using Intellij. One thing it often does in make suggestions on
    >> how to improve your code. One it made, I thought was illegal till I
    >> tried it out.
    >>
    >>
    >> If you have code like this:
    >>
    >> case 1:
    >> int x = expression;
    >> break;
    >> case 2:
    >> x = expression;
    >> break;
    >>
    >> that is LEGAL even though program flow does not flow through the
    >> definition. You DON'T have to promote x out of the switch. You can
    >> think of it that it works AS IF you always fell through each case. The
    >> key to this mystery is understanding that local variables are not
    >> actually allocated where you define them. They all get allocated at
    >> once when you enter the method by reserving N stack slots, where they
    >> effectively became extra dummy parameters to your method.

    >
    >
    > It doesn't work if you put curly brackets around your case code like
    > this, which is how I prefer to write my switches:
    >
    > case 1:
    > {
    > int x = expression;
    > break;
    > }
    > case 2:
    > {
    > x = expression;
    > break;
    > }


    Those don't seem to be the same x.


    > javac Main.java

    Main.java:13: cannot find symbol
    symbol : variable x
    location: class Main
    x = expression;
    ^
    Main.java:18: cannot find symbol
    symbol : variable x
    location: class Main
    System.out.println(x);
    ^
    2 errors

    ---------------------------------------------

    class Main {
    public static void main(String[] args) {
    int expression = 42;

    switch(2) {
    case 1:
    {
    int x = expression;
    break;
    }
    case 2:
    {
    x = expression;
    break;
    }
    }

    System.out.println(x);

    }
    }
     
    Jeffrey Schwab, Feb 24, 2006
    #7
  8. Roedy Green

    Roedy Green Guest

    On Fri, 24 Feb 2006 14:09:40 +0100, Timo Stamm <>
    wrote, quoted or indirectly quoted someone who said :

    >> key to this mystery is understanding that local variables are not
    >> actually allocated where you define them. They all get allocated at
    >> once when you enter the method

    >
    >It's not per method, but per block:
    >
    > {
    > int x = 0;
    > }
    > x = 3; // unknown variable
    >
    >
    >
    >Timo


    From my reading the JVM virtual machine spec, that is not correct.
    they are all allocated slots on method entry. The compiler could share
    slots when it is safe, but the actual allocation is done as part of
    the call to set up the stack frame which sets the base for allocating
    parameters and local variables all on the stack. When you call any
    method you push parameters for it, then its return address and jump
    the method. It then allocates its locals by bumping the stack pointer
    up enough slots to leave room.

    The only time this causes serious trouble is in recursion, because you
    get a multiplier effect for every bit of padding in the local
    variables.

    At the JVM level, the type of each variable in a local slot is fixed.
    You could not use the slot for a reference then recycle it as an int.
    Of course AOT or Hotspot can do that sort of optimisation so long as
    the next effect is the same.
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Java custom programming, consulting and coaching.
     
    Roedy Green, Feb 24, 2006
    #8
  9. Roedy Green

    Roedy Green Guest

    On Fri, 24 Feb 2006 14:38:43 GMT, Jeffrey Schwab
    <> wrote, quoted or indirectly quoted someone who
    said :

    >> case 1:
    >> {
    >> int x = expression;
    >> break;
    >> }
    >> case 2:
    >> {
    >> x = expression;
    >> break;
    >> }

    >
    >Those don't seem to be the same x.


    in that "case" you have logically two different local variables named
    x.


    case 1:
    {
    int x = expression;
    break;
    }
    case 2:
    {
    int x = expression;
    break;
    }

    which is most of the time what you intend. You doing similar little
    calculations for each case. x is local to each case.

    By the way, for you Pascal programmers, those {} have no speed
    penalty. They are purely for explaining your scope. No new block gets
    allocated.

    the JVM is very simple minded. local variables are numbered slot
    numbers. If you allocated them on the fly, the compiler would need to
    track stack depth. Not that hard, but then the slot number would
    change depending no how many temporaries were on the stack. That would
    complicate low level debugging. So Sun allocated all locals up front
    so they could have fixed slot numbers.
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Java custom programming, consulting and coaching.
     
    Roedy Green, Feb 24, 2006
    #9
  10. Roedy Green

    Timo Stamm Guest

    Jeffrey Schwab schrieb:
    > Daniel Dyer wrote:
    >> It doesn't work if you put curly brackets around your case code like
    >> this, which is how I prefer to write my switches:
    >>
    >> case 1:
    >> {
    >> int x = expression;
    >> break;
    >> }
    >> case 2:
    >> {
    >> x = expression;
    >> break;
    >> }

    >
    > Those don't seem to be the same x.


    I think that was Daniels point. The curly brackets define a new block.
    So the local variables are only visible within each block.


    Timo
     
    Timo Stamm, Feb 24, 2006
    #10
  11. Roedy Green

    Roedy Green Guest

    On Fri, 24 Feb 2006 16:13:50 +0100, Timo Stamm <>
    wrote, quoted or indirectly quoted someone who said :

    >>> case 1:
    >>> {
    >>> int x = expression;
    >>> break;
    >>> }
    >>> case 2:
    >>> {
    >>> x = expression;
    >>> break;
    >>> }

    >>
    >> Those don't seem to be the same x.

    >
    >I think that was Daniels point. The curly brackets define a new block.
    >So the local variables are only visible within each block.


    I think the point got lost that the code would not compile with the
    {}.
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Java custom programming, consulting and coaching.
     
    Roedy Green, Feb 24, 2006
    #11
  12. Roedy Green wrote:
    > On Fri, 24 Feb 2006 16:13:50 +0100, Timo Stamm <>
    > wrote, quoted or indirectly quoted someone who said :
    >
    >
    >>>>case 1:
    >>>>{
    >>>> int x = expression;
    >>>> break;
    >>>>}
    >>>>case 2:
    >>>>{
    >>>> x = expression;
    >>>> break;
    >>>>}
    >>>
    >>>Those don't seem to be the same x.

    >>
    >>I think that was Daniels point. The curly brackets define a new block.
    >>So the local variables are only visible within each block.

    >
    >
    > I think the point got lost that the code would not compile with the
    > {}.


    You both are right, of course. I mis-read Daniel's post. Thanks.
     
    Jeffrey Schwab, Feb 24, 2006
    #12
  13. "Roedy Green" <> wrote in
    message news:...
    > On Fri, 24 Feb 2006 14:09:40 +0100, Timo Stamm <>
    > wrote, quoted or indirectly quoted someone who said :
    >
    >>> key to this mystery is understanding that local variables are not
    >>> actually allocated where you define them. They all get allocated at
    >>> once when you enter the method

    >>
    >>It's not per method, but per block:
    >>
    >> {
    >> int x = 0;
    >> }
    >> x = 3; // unknown variable
    >>
    >>
    >>
    >>Timo

    >
    > From my reading the JVM virtual machine spec, that is not correct.
    > they are all allocated slots on method entry.


    But that's not really relevant. The key to your mystery is that the scope
    of a local variable (that is, the places where it can be used) is from its
    declaration to the end of its enclosing block, and case statements don't
    begin new blocks.
     
    Mike Schilling, Feb 25, 2006
    #13
  14. Roedy Green

    Andy Dingley Guest

    On Fri, 24 Feb 2006 13:39:42 GMT, Roedy Green
    <> wrote:

    >That is debatable, but in does have the effect of narrowing the scope
    >of a variable, which is general is a good thing.


    It doesn't (AIUI). The scope of the variable is defined by the blocks
    that contain it, not quite the literal execution path that the switch
    might suggest. Declaring inside the switches is both unclear and not
    even restricting the scope any further than you could do by declaring it
    just outside the switch.

    If I wantd to have code like this, I'd write Perl.
     
    Andy Dingley, Feb 25, 2006
    #14
  15. "Andy Dingley" <> wrote in message
    news:...
    > On Fri, 24 Feb 2006 13:39:42 GMT, Roedy Green
    > <> wrote:
    >
    >>That is debatable, but in does have the effect of narrowing the scope
    >>of a variable, which is general is a good thing.

    >
    > It doesn't (AIUI). The scope of the variable is defined by the blocks
    > that contain it, not quite the literal execution path that the switch
    > might suggest. Declaring inside the switches is both unclear and not
    > even restricting the scope any further than you could do by declaring it
    > just outside the switch.


    This last is not true.

    int x
    switch (expr)
    {
    int y;
    ...
    }

    // x is still in scope, y is not.
     
    Mike Schilling, Feb 26, 2006
    #15
  16. "Mike Schilling" <> burped up warm pablum in
    news:u0lMf.35443$:

    >> It doesn't (AIUI). The scope of the variable is defined by the blocks
    >> that contain it, not quite the literal execution path that the switch
    >> might suggest. Declaring inside the switches is both unclear and not
    >> even restricting the scope any further than you could do by declaring it
    >> just outside the switch.

    >
    > This last is not true.



    By "last" I assume you mean, "Declaring inside the switches is both unclear
    and not even restricting the scope any further than you could do by
    declaring it just outside the switch."

    > int x
    > switch (expr)
    > {
    > int y;
    > ...
    > }
    >
    > // x is still in scope, y is not.


    In your example, y is out of scope because of the block "{}" snd not the
    switch statement.
     
    Tris Orendorff, Feb 27, 2006
    #16
  17. "Tris Orendorff" <> wrote in message
    news:Xns977794AC922B6RepublicPicturesLtd@216.221.81.119...
    > "Mike Schilling" <> burped up warm pablum in
    > news:u0lMf.35443$:
    >
    >>> It doesn't (AIUI). The scope of the variable is defined by the blocks
    >>> that contain it, not quite the literal execution path that the switch
    >>> might suggest. Declaring inside the switches is both unclear and not
    >>> even restricting the scope any further than you could do by declaring it
    >>> just outside the switch.

    >>
    >> This last is not true.

    >
    >
    > By "last" I assume you mean, "Declaring inside the switches is both
    > unclear
    > and not even restricting the scope any further than you could do by
    > declaring it just outside the switch."


    Just the part about "not even restricting the scope any further " What's
    unclear is largely in the eye of the beholder.


    >
    >> int x
    >> switch (expr)
    >> {
    >> int y;
    >> ...
    >> }
    >>
    >> // x is still in scope, y is not.

    >
    > In your example, y is out of scope because of the block "{}" snd not the
    > switch statement.


    A switch statement always controls a block.
     
    Mike Schilling, Feb 27, 2006
    #17
  18. "Mike Schilling" <> burped up warm pablum in
    news:sIIMf.38047$:

    >> By "last" I assume you mean, "Declaring inside the switches is both
    >> unclear
    >> and not even restricting the scope any further than you could do by
    >> declaring it just outside the switch."

    >
    > Just the part about "not even restricting the scope any further "
    > What's unclear is largely in the eye of the beholder.
    >
    >
    >


    True! Very true.
     
    Tris Orendorff, Mar 4, 2006
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. java_typhoon
    Replies:
    9
    Views:
    903
    Oliver Wong
    Apr 6, 2006
  2. George Zhou
    Replies:
    2
    Views:
    356
    MiniDisc_2k2
    Jul 11, 2003
  3. Daniel Waite
    Replies:
    2
    Views:
    231
    Daniel Waite
    May 2, 2008
  4. Andries

    I know, I know, I don't know

    Andries, Apr 23, 2004, in forum: Perl Misc
    Replies:
    3
    Views:
    253
    Gregory Toomey
    Apr 23, 2004
  5. Mark Lawrence
    Replies:
    63
    Views:
    218
    Robert Kern
    May 17, 2014
Loading...

Share This Page