4castle 4castle -5 years ago 133
Java Question

Is the scope of a variable initialized in a for loop declaration actually more than just block scope?

Consider a

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
has "block" scope.

However, why is it that variables declared within the
loop are not accessible at

For example, why is
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
, but not any concerning the scope of
within the
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
loop declarations have a higher scope than their curly brackets.

Answer Source

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:

  • It would be bad for readability if you had to look inside the loop body for variables declared there2.
  • 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 seriously doubt that the Java designers even bothered to consider doing this kind of thing.

2 - It is bad enough that something in the loop body could modify a loop variable. :-(

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download