• 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 Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Gotcha!!

 
Sheriff
Posts: 5782
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Do you think the following code compiles??
Okay, be honest and don't try to compile it. Just try to guess!!
<PRE>
class Weirdo
{
void someMethod()
{
for ( int i = 0 ; i < 3 ; i++ )
int j = i;
}
}
</PRE>

Ajith
 
Ranch Hand
Posts: 289
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ajith,
Not only do I think the code compiles, but if it had to be run, It should also run perfectly well. I am almost certain here.

Herbert.
 
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I agree with Herbert.
Whats' the catch ?
Well, there is the necessity to provide
a main() to run it ofcourse . Anything
else?
Regds.
- satya
 
Ajith Kallambella
Sheriff
Posts: 5782
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I was waiting for more replies to come in, but I can't hold it any longer he he he
Okay guys, now use your "beloved" javac to compile this one. I should warn you, fasten your seat belts.....
Use JDK 1.2. I will be waiting to hear your experiences....


Ajith
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

i gotit.....
yup, weird!
I could get around, but amnot posting it
ritght away....
Regds.
- satya
 
Herbert Maosa
Ranch Hand
Posts: 289
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ajith,
trust me, I didn't compile it, but on second consideration, the code will not compile.But I guess you want more people to play with it, so I wont say why, unless you permit me to. Wierdo !!!

Herbert.
 
Ajith Kallambella
Sheriff
Posts: 5782
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Satya and Herbert,
Lets wait for a while. You know, I am such a sadist , I want more people to sob!. Don't post work around/explanations yet.

Ajith

[This message has been edited by Ajith Kallambella (edited May 15, 2000).]
 
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
interesting Ajith
Got around it with the help of the error mesg!
Waiting for some explanation on this behavior..:-)
 
Ranch Hand
Posts: 136
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ajith,
When I first saw the code(I did not see the rest of the forum), my answer was it will not compile. Now, I tried and confirmed my answer. Waiting to add my views on this behavior.
Suma.
[This message has been edited by Suma Narayan (edited May 15, 2000).]
 
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
My lips are sealed .This is my first time on javaranch.Don't tell me I need braces.I thought my teeth were fine.Waiting for the explanation.
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ajit, you are indeed a sadist. Interesting example. I admit, I thought it would compile too - but when I saw it didn't, I remembered some obscure rules in the JLS that account for it not compiling. The question I would have is: does this (admittedly somewhat strange) behavior prevent you from doing anything useful? In the example you give, the variable j is only in scope for one line right? So what point is there in assigning it a value? I believe you will find that if you try to do anything useful with j, you will be able to get it to compile. Of course, I could be wrong, in which case I'm sure someone will let me know...

[This message has been edited by Jim Yingst (edited May 15, 2000).]
 
Ajith Kallambella
Sheriff
Posts: 5782
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Okay guys. I think it is time to dig the grave open. Here is my explanation, which may not be very convincing. Please pour in your views and let's summarise it at the end.
According to JLS, Every local variable declaration statement is immediately contained by a block. . Because declaration is an executable statement, the compiler expects it to belong to a block. One may ask, if no explicit block is specified, why can't the compiler associate the statement with the immediate block available? I don't know why, but this behaviour can also be seen if you just put a free flowing statement in a class declaration.
<PRE>
class MyClass {
int i = 10 ;

// If you don't enclose the following line
// in a block, the compiler balks.
i = i + 10;
}
</PRE>

One can observer the same behaviour with any block statement for, do, while etc. All you need to do is to have a declaration with assignment statement immediately after the block, without brackets. Consider a very simple variant of my example
<PRE>
class Weirdo
{
void someMethod()
{
for ( int i = 0 ; i < 3 ; i++ )
// Just the declaration is enough to blow it up!
int t ;
}
}
</PRE>

I think another reason why compiler gives the error is it cannot resolve the name space. Every executable statement belongs to a namespace and symbol references can shadow similarly named symbols in other namespaces. Remember blocks creates namespaces? By enforcing brackets around the declaration, compiler is making sure there is no namespace conflict.
That's about all I have to offer.

Ajith
 
Ajith Kallambella
Sheriff
Posts: 5782
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey Jim,
A quick response to your message. You might have seen a code like this in most of the mock exams, usually questions relating to GC.
<PRE>
class HowManyStringsGCed
{
public static void main( String args[] )
{
for ( int i = 0 ; i < 10 ; i++ )
{
String t = new String("Hello");
}
}
}
</PRE>
Here, I have no choice but to put the braces around the only one statement in the for loop. Agreed, I am not doing anything with the t, but what if I wanted to write a code like this ??
Perhaps one can indeed think of a better real-life example.

Ajith
 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
<code><pre>
class a{
int i=10;
}//compiles

class a{
int i=10;
i=i+10;
}//does not

class a{
{
int i=10;
i=i+10;
}
}//does
</pre></code>
Please explain in easier terms.

[This message has been edited by Jim Yingst (edited May 15, 2000).]
 
Ajith Kallambella
Sheriff
Posts: 5782
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Am I lost here? I thought Herbert, Satya and Suma were waiting to post their explanations.....hello..knock..knock..knock...
Ajith
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Basically, the rules are set up to try to disallow you from making a local variable declaration the only thing in a loop. The idea is that there is never any point to declaring a local variable if it's just going to go out of scope immediately after the declaration. True, you can circumvent this using braces. But that just shows that the Java compiler can't prevent all possible error you might make, just some. Silly GC examples notwithstanding, I'm convinced there's nothing useful you could do with code like this that is prevented by the compiler in this case. It's much like asking "if a tree falls in the forest and no one is there to hear it, does it make a noise?" Answer - it doesn't matter.
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ajith:
I thought you pretty much summarized the rule here....
It doesnot compile since the scope is not valid.
Regds.
- satya
 
Suma Narayan
Ranch Hand
Posts: 136
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ajith,
I was going to quote the same ,which u did from JLS.
Every local variable declaration statement is immediately contained by a block.
I think you and jim have explained everything.

suma.
 
Rancher
Posts: 241
Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Shashank,
If I'm not mistaken, when you add those braces you create an instance initialization block, which is like a static initialization block for instances. So the compiler knows the purpose of that code - to be called during instance initialization. Otherwise, the assignment floats in space, since the compiler's just looking for declarations in the code body at this point.
Eric B.
 
Herbert Maosa
Ranch Hand
Posts: 289
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ajith, Satya
I think the issue has little , if not nothing to do with scope. I say thus because this works........
---------------------------------------
int j =0;
for (int i=0;i<3;++i)
j=i;
----------------------------------------
Jim,
I am not very conviced with the following statement and I quote :
------------------------
Basically, the rules are set up to try to disallow you from making a local variable declaration the only thing in a loop
----------------------------
You will find out that this works fine:
do {
int j;
}while(true);

I am cooking my version.
Herbert.
 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all,
Interesting discussion.
Jim your statement :
I'm convinced there's nothing useful you could do with code like this that is prevented by the compiler in this case.
holds water if you are only defining primitive data types. What if you were defining an instance of a class? Wherein the constructor for the class would do something useful, and you wanted it done ten times?
I used the compiler to confirm that the rules are the same for defining a class in this manner, and they are.
public class Class1 {
public static void main( String args ) {
for ( int i = 0; i < 10; i++ )
SomeObject someObject = new SomeObject();
}
}
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Herbert- on your second point (the one addressed to me): you are right, it's possible to code a loop with a local variable declaration as the only thing in the loop. I acknowledged this in my post - "True, you can circumvent this using braces." I'm not saying that there is an absolute ban on this type of statements, although there could be (i.e. your example doesn't do anything either, so if the compiler had disallowed it that would've been OK). I think that the reason the rules allow one and not the other is simply because it would have taken a little more effort to plug the loophole for braces, and it wasn't a high priority for anyone to fix. It's not really broken after all, just kind of inconsistent. And not worth changing in later releases, as it would cause backward compatibility issues - legal but useless code would no longer compile. It's not a big enough issue to force people to go and fix their old code.
As for your first point, I think that you've demonstrated that scope is an issue. By declaring j outside the loop, its scope now extends outside the loop - which means that the changes to j inside the loop are no longer irrelevant - they can affect the outside world. Which is why this code must be allowed to compile - it's not "useless" in the way the other examples were.
Note also that some of the definitions in the JLS are, shall we say, non-intuitive:
  • <code>int j;</code> is a declaration, not a statement.
  • <code>int j = i;</code> is a declaration with initializer, but still not a statement.
  • <code>j = i;</code> is a statement.
  • Any block (pair of matching braces with stuff in between) is a statement.
  • A block may contain one or more declarations and/or statements.
  • So, <code>{ int j = i; }</code> is a block, and therefore a statement.

 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ken- good point. It's not just constructors though - if you have a declaration with an initializer, there are all sorts of things you can do in the initializer that can have an effect in the outside world:
<code><pre>for ( int i = 0; i < 10; i++ )
int j = someMemberVariable++;
</pre></code>
<code><pre>for ( int i = 0; i < 10; i++ )
int j = deleteRecordsFromDBAndReportNumberDeleted();
</pre></code>
<code><pre>for ( int i = 0; i < 10; i++ )
SomeObject someObject = new SomeObject();
</pre></code>
But the thing is, the declaration part of the code is still useless. The variable j is still completely ignored, and you'd have the same results with the following:
<code><pre>for ( int i = 0; i < 10; i++ )
someMemberVariable++;
</pre></code>
<code><pre>for ( int i = 0; i < 10; i++ )
deleteRecordsFromDBAndReportNumberDeleted();
</pre></code>
<code><pre>for ( int i = 0; i < 10; i++ )
new SomeObject();
</pre></code>

[This message has been edited by Jim Yingst (edited May 16, 2000).]
 
Shashank Jha
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
does the compiler check for usefullness too?
class a{
int i;}
 
Herbert Maosa
Ranch Hand
Posts: 289
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Jim,
I reconsidered my first point,to which you have responded and came up with the following snipet:
-----------
for (int i =0; i<3;++i)
int j=(i =0);
-----------------------------------
never mind the semantics of the loop, but my point is: In this case j is declared within the loop, the snipet compiles fine. It appears to me like there is also something to do with initializing a local variable with another local variable in the same scope without the first variable being assigned a value. To me it appears like at compile time, all the compiler checks is whether the for loop is correctly formed, and not whether the initial value,0, has been assigned to the variable i. So when the code comes to int j=i; it appears , in the view of the compiler that we are probably declaring and initializing j with a variable i that has no value.
How do you consider this ?
Herbert.
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Herbert- I can't get that code to compile. JDK 1.1.8 and JDK 1.2.2 complain "invalid declaration". JDK 1.3.0 complains ".class expected" ( ) and "not a statement". The last message is probably the most accurate - according to the JLS, <code>int j = (i = 0);</code> is not a statement, it's a declaration.
If you do get it to compile, what compiler are you using? On what platform? (I'm on Windows NT). Perhaps you could show the complete code you're using to compile - here's mine:

Shashank- well, the compiler checks to see if the rules of Java are being obeyed. In a few cases, the rules of Java prevent useless statements. But there are plenty of other useless statements you could make which are not prevented. It's not a primary motivation behind the rules - just an occasional side effect.
 
Herbert Maosa
Ranch Hand
Posts: 289
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Jim,
Actually you are right,it compiled just becuase i had enclosed the statement (int j =(i =2))in braces, and this really makes a big difference and invalidates my argument, to some extent. I had it as follows......

class Wierdo{
void aMethod(){
for (int i=0; i<3;++i){
int j = (i =2);
}
}
}
and if I remove the {} of the for statement, I get the same error, back to square one.
Hey
But Jim, I still think that the error has little to do with the scope of the variable i, because if you try this
-------------------
for (int i=0;i<3;++i)
int j=3;
---------------------------------------
You will probably get the same error, though here you are explicitly assigning the value 3 to j. At least my compiler gives me the same error.
Herbert.
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Herbert- I agree that the issue has little to do with the scope of i - it's the scope of j that is the issue, I think. Since j is only defined inside the for loop, the declaration of j will be useless unless there are other statements inside the loop after the declaration which make some use of the variable j.
So, if you were talking about the scope of i while I was talking about the scope of j, then we're not really disagreeing here. I think.
 
Ajith Kallambella
Sheriff
Posts: 5782
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Jim,
Since I don't have a JDK 1.3.0 and I am currently travelling, can you check if it gives a different ( better ?? ) error message for my original code?
I too am beginning to think, perhaps this is not a scope issue at all.....
Thanks,
Ajith
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
jdk 1.3.0 complains ".class expected" and "not a statement", as for Herbert's example.
It's certainly possible to explain the results without thinking about scope. The JLS does not allow a declaration as the entire body of a loop - it must be part of a block. Period. The scope only comes into play when we ask why the JLS is written this way - the extremely limited scope of the variable makes the declaration completely useless. At least, that's my guess as to why the rules are written that way.
 
Ken Baldwin
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Jim,
I got the point, thanks.
I was focusing more on whether something useful could be done on the single line.
The declaration of a variable is absolutely meaningless, as you have stated a number of times in this post.
Ken
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Heh. I did repeat myself quite a bit there. Guess I should reread the thread occasionally to remind myself which points have already been driven into the ground.
Going back to my earlier statement:
"I'm convinced there's nothing useful you could do with code like this that is prevented by the compiler in this case."
The compiler doesn't prevent you from doing any of the potentially useful things we've discussed - it only prevents you from including the useless declaration part (unless of course you use braces, and then you can sneak it in anyway). Any useful code can be easily modified to get it through the compiler.
 
Ajith Kallambella
Sheriff
Posts: 5782
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK guys, here goes another "useless statement". The error you get is "Invalid Expression statement"
<PRE>
class UselessStatementDemo
{
public static void main( String[] s )
{
9 << 2 ;
}
}
</PRE>
As I said before, I have begun to think the compiler tests for usability of every executable statement. Huh??
Ajith
 
Desperado
Posts: 3226
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
With the latest (non-beta) version of JDK (1.3) I get:
"not a statement"
Which is true.
 
Shashank Jha
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Sheriff!!
reply
    Bookmark Topic Watch Topic
  • New Topic