And that is my point, if this (declaring variables anywhere) is NOT good for other control blocks (like "if" or any other), then what makes "for" so special?
I think the speciality of the 'for' iterator is quite obvious. A 'for..to' loop always has exactly one iterator. The iterator variable of the loop is read/write outside the loop, but readonly within the loop.
Well, point to you, good answer.
This is probably out of the need of an implementation detail, which allows the compiler to optimize the loop behaviour, but nevertheless.
I am not sure, if I want this to be extended. Actually I am quite sure I do not, but that is personal opinion.
But in this case (and while I do NOT vote for it), I would say the way to extend this, would be to add a modifier in the var section
and keep the for loop as it is.
That is the "for" loop can NOT declare a new variable, it has to use one from the "var" declaration (a modeswitch may be introduced to force it to only use "marked" ones)
Any variable marked as "iterator" (or whatever the keyword) will only be allowed to be used as "for" loop iterator and nowhere else.
This however would be mainly to highlight the fact, that the variable is special (read only).
Any effect it has on the uninitialized issues, would be a mere side effect. Otherwise we would need lots of other special flags, for other cases of uninitialized vars.
This would for example allow to prevent the following:
procedure Bar;
var
i: Integer;
procedure Foo;
begin
i:=9; // we can modify i here, which can cause all kind of undesired effects
end;
begin
for i := 1 to 10 do begin
Foo;
writeln(i);
end;
end;
And by the way, this example only works, if the
"iterator" variable can be read outside the loop (assuming Foo would read, instead of write). And that would include "after the loop" too (Foo could be called after the loop).
So this example shows, that a variable with a scope set to the loop itself, would actually break existing language features. (the feature being reading the var in Foo, not the abuse of writing to it)
Yes I know it is optional, but if there are cases where it can not be used at all (not even optional), then that means that even if you want the feature you are left with some code that even you must write in the old way, and even you still will not get the "protection" you seek.
So the new feature would be incompleteTherefore: "var i: integer iterator;" should make it read-only, but still allow access anywhere.
But still, the iterator variable needs a space in memory. This has a certain size and location. The iterator could be defined as local or global variable. There may be reasons for both, especially in embedded programming. So a declaration is required and the var section is the correct place for that.
At the moment "for" iterators must be local variables. (probably due to the same implementation detail)
Still, a self-declared iterator variable could be allowed.
IMHO, no.
But: Why?
What extra good would they bring?
This would be an introduction of self decleration, a simple typo could change the type of the iteration variable if a explicit declared variable was intended. I see that this is not part of the pascal philosophy...
You argue my case. Thanks.
What makes the uninitialized var after a loop so different to other uninitialized var?
For me its quite strange that the variable is initialized if the loop was interrupted by break/goto but not if it was properly finished. If I want to use the feature in case that the loop was interrupted than I first have to check if the loop even was interrupted, otherwise I couldn't rely on the iteration variables value. This means flags or something is needed. But instead such efforts I could just copy the iteration variable inside the loop, so that feature seems useless...
This is an argument why the "break" behaviour is not a good idea (though exceptions, and an "except" block would work).
But it does not answer my question. My understanding is this:
A loop iterator is uninitialized after the loop. We want protection from accidentally using an uninitialized variable (I intentionally made this statement generic, applying to any uninitialized var).
- Why do we want special/extra protection, if that uninitialized var was a "for" iterator before?
- IMHO, *ALL* uninitialized deserve the same lever of attention/protection.
- An application certainly will be same as buggy if it hits an uninitialized var never mind if this was a "for" iterator, or otherwise uninitialized.
So again:
What makes the uninitialized var after a loop so different to other uninitialized var?