Java Forum / General / March 2006
I did not know that was legal
Roedy Green - 24 Feb 2006 11:51 GMT 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.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
paul@atom.sbrk.co.uk - 24 Feb 2006 12:06 GMT > 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 [quoted text clipped - 10 lines] > > that is LEGAL It might be legal, but does it really *improve* your code??
Paul
Roedy Green - 24 Feb 2006 13:39 GMT >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.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Andy Dingley - 25 Feb 2006 17:31 GMT >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.
Mike Schilling - 26 Feb 2006 16:51 GMT >>That is debatable, but in does have the effect of narrowing the scope >>of a variable, which is general is a good thing. [quoted text clipped - 4 lines] > 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.
Tris Orendorff - 27 Feb 2006 19:36 GMT >> 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 [quoted text clipped - 3 lines] > > 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) [quoted text clipped - 4 lines] > > // 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.
Mike Schilling - 27 Feb 2006 19:48 GMT >>> 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 [quoted text clipped - 8 lines] > 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) [quoted text clipped - 7 lines] > In your example, y is out of scope because of the block "{}" snd not the > switch statement. A switch statement always controls a block.
Tris Orendorff - 04 Mar 2006 18:51 GMT >> By "last" I assume you mean, "Declaring inside the switches is both >> unclear [quoted text clipped - 3 lines] > 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.
Thomas Fritsch - 24 Feb 2006 12:28 GMT > If you have code like this: > [quoted text clipped - 7 lines] > 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; }
 Signature "Thomas:Fritsch$ops:de".replace(':','.').replace('$','@')
Timo Stamm - 24 Feb 2006 13:09 GMT 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
Roedy Green - 24 Feb 2006 14:59 GMT >> key to this mystery is understanding that local variables are not >> actually allocated where you define them. They all get allocated at [quoted text clipped - 8 lines] > >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.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Mike Schilling - 25 Feb 2006 02:23 GMT >>> key to this mystery is understanding that local variables are not >>> actually allocated where you define them. They all get allocated at [quoted text clipped - 11 lines] > 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.
Daniel Dyer - 24 Feb 2006 13:39 GMT > 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 [quoted text clipped - 16 lines] > 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.
 Signature Daniel Dyer http://www.dandyer.co.uk
Jeffrey Schwab - 24 Feb 2006 14:38 GMT >> 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 [quoted text clipped - 30 lines] > 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);
} }
Roedy Green - 24 Feb 2006 15:06 GMT On Fri, 24 Feb 2006 14:38:43 GMT, Jeffrey Schwab <jeff@schwabcenter.com> wrote, quoted or indirectly quoted someone who said :
>> case 1: >> { [quoted text clipped - 8 lines] > >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.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Timo Stamm - 24 Feb 2006 15:13 GMT Jeffrey Schwab schrieb:
>> It doesn't work if you put curly brackets around your case code like >> this, which is how I prefer to write my switches: [quoted text clipped - 11 lines] > > 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
Roedy Green - 24 Feb 2006 20:11 GMT >>> case 1: >>> { [quoted text clipped - 11 lines] >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 {}.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Jeffrey Schwab - 24 Feb 2006 21:04 GMT >>>>case 1: >>>>{ [quoted text clipped - 14 lines] > 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.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|