问题
In the following code, I'm using the variable name n
for both a local variable and a loop counter:
proc main()
{
var n = 700;
writeln( "n (before loop) = ", n );
for n in 1..3 {
writeln( "n = ", n );
}
writeln( "n (after loop) = ", n );
}
and the result is
n (before loop) = 700
n = 1
n = 2
n = 3
n (after loop) = 700
Does this mean that the for
loop always creates a new loop variable, in a way similar to for (int n = 1; n <= 3; n++)
rather than for (n = 1; n <= 3; n++)
(in C-like languages)?
(Background) I was playing with the following code using ref
, and since the loop did not change the value of baa
in the outer scope, I imagined that b
is probably created as a new variable...
proc main()
{
var baa: int = 700;
ref b = baa;
writeln( "baa (before loop) = ", baa );
for b in 1..3 {
writeln( "b = ", b, " baa = ", baa );
}
writeln( "baa (after loop) = ", baa );
}
Result:
baa (before loop) = 700
b = 1 baa = 700
b = 2 baa = 700
b = 3 baa = 700
baa (after loop) = 700
回答1:
Does this mean that the for loop always creates a new loop variable, in a way similar to
for (int n = 1; n <= 3; n++)
rather thanfor (n = 1; n <= 3; n++)
(in C-like languages)?
Yes, that's right. Chapel's for
, forall
, and coforall
loops each declare new index variables for their iterations. In the forall
and coforall
cases this is done out of necessity since different tasks will be executing different iterations and each will need its own copy of the index variable. Our for
loops adopt the same strategy for consistency and convenience. If you want to modify an outer variable within a Chapel [co
]for
[all
] loop, you would need to do it in the loop's body or iterator expression.
The compiler could (and perhaps should) emit a warning for cases like yours in which a loop variable shadows a variable at the same scope, to avoid confusion. If you'd like to advocate for this behavior, please consider filing a GitHub issue for it.
来源:https://stackoverflow.com/questions/49948407/whether-loop-variables-are-always-freshly-created