Reputation: 33496
Consider a for
loop with a counter:
for (int i = 0; i < 100; i++ /* `i` is visible here */) {
/* `i` is visible here */
}
/* `i` not visible here */
All is well. We say that i
has "block" scope.
However, why is it that variables declared within the for
loop are not accessible at i++
?
For example, why is j
not in scope here, when it also has "block" scope and was declared in a time period that is before i += j
?
for (int i = 0; i < 100; i += j /* only `i` is visible here */) {
int j = 1;
/* `i` and `j` are visible here */
}
/* `i` and `j` are not visible here */
I have seen many questions concerning the scope of i
, but not any concerning the scope of j
within the for
loop parentheses. Does this mean that there is technically another scope that nobody talks about which is "for-loop declaration scope"? If so, I'm interested in how this scope is defined in specs such as Java or C# and what scope it is generally referred to as by programmers.
Edit: Yes, I understand that I can declare the loop as for (int j, i = 0; i < 100; i += j)
, but that still demonstrates that for
loop declarations have a higher scope than their curly brackets.
Upvotes: 4
Views: 1466
Reputation: 719326
The facial reason for this that JLS 6.3 specifies the scoping that way:
The scope of a local variable declared in the ForInit part of a basic for statement (§14.14.1) includes all of the following:
- Its own initializer
- Any further declarators to the right in the ForInit part of the for statement
- The Expression and ForUpdate parts of the for statement
- The contained Statement
The "contained statement" the for
body. There are no special scoping rules for variables defined in a for
body. The normal rules apply. (They are also in JLS 6.3.)
The reasons behind this language design include (I guess1) the following:
The logic to determine whether the variable declared in the loop was definitely initialized would be hard to specify, and difficult for programmers to understand. Example:
for (i = 1; i < 10; i = i + j) {
int j;
if (i > 3) {
j = 42;
}
// do stuff
}
1 - The real reasons would only be known to the designers of C ... back in the 1970's. I doubt that the Java designers considered doing it differently from C. They were trying to make Java "C-like".
2 - It is bad enough that something in the loop body could modify a loop variable. :-(
Upvotes: 4
Reputation: 3943
A very interesting question. You raise a very good point that j should be visible if you look at it from runtime-perspective as increment expression is invoked after the iteration.
But from compiler perspective, when it reads the for loop statement i.e. (int i = 0; i < 100; i += j)
, it would expect j to be declared already.
I guess you can say i has an additional statement scope as compared to the block scope that both i and j have.
Upvotes: 0
Reputation: 1591
The first Scope is begins with void main{ } than after other inner blocks with like your for loop scope,and all variables declared with this first block are visible to all inner block of scope and we must declared variable before use it(in your case variable j) you used variable inside for loop without declared it, so it is not possible to use it before declarations and our cursor arrived at for loop due to top to bottom approach line by line first of all it check variable are declared or not?
Upvotes: 0
Reputation: 26
The variable J is referred before the declaration/initialization. When first time loop will be executed JVM would not have a reference to it.
You have initialized the variable j inside the loop.
I hope this clears your question.
Upvotes: -1