J. David Bryan wrote:
On 20 May 2000, at 9:31, Russ Whitaker wrote:
So what does the Pascal specs say?
The Extended Pascal standard, section 6.9.3.9.1, says:
"After a for-statement is executed, other than being left by a goto-statement, the control-variable shall be undefined."
That's remarkably clear. :-) That means that variable "b" in the code below isn't guaranteed to be true:
In fact, i = 10 in the current GPC version (but don't rely on it :-).
procedure p; var i : integer; b : Boolean; begin for i := 1 to 10 do ; b := (i > 10); end;
The next part of the standard is a bit less clear:
"Neither a for-statement nor any procedure-and-function-declaration-part of the block that closest-contains a for-statement shall contain a statement threatening (see 6.9.4) a variable-access denoting the variable denoted by the control-variable of the for-statement."
I believe that says that you can't modify the control variable of a for- statement (a "threat" is defined in the standard as one of ten ways that a variable may be assigned a value).
Including a `for' statement (item g :-). Therefore I conclude that a `for' statement by itself is illegal in Pascal. Alright, we'll take it out of the next GPC release. Just kidding...
So this would clearly be illegal:
procedure p; var i : integer; begin for i := 1 to 10 do i := 11; end;
However, it also says that a block containing a for-statement cannot contain a threat to the control variable. In other words, this would be illegal too:
procedure p; var i : integer; begin i := 0; for i := 1 to 10 do end;
I suppose the reason is to disallow something like this:
procedure p; var i : integer; label 1, 2, 3; begin goto 1; 2: i := 11; goto 3;
1: for i := 1 to 10 do begin goto 2; 3: end
end;
...which is functionally equivalent to the second code example.
Yes, but is a goto into a loop legal at all (the last sentence of 6.9.2.4 seems to indicate not to me, but I'm not completely sure)? If it is legal, what should the following code do?
procedure p; var i : integer = 42; label 1; begin goto 1; for i := 1 to 10 do begin 1: Writeln (i) end end;
So it would seem that to comply with the EP standard, GPC must prohibit any threat (i.e., variable assignment) to a for-statement control variable anywhere within the scope of that variable, and not just within the for- statement itself.
This would mean that the loop variable could practically not be used outside of the for loop. If this is really true, I'd really favour a syntax that makes this clear (like `for i : Integer = 1 to 10 do ...'), so i has only the corresponding scope.
Frank
Frank Heckenbach a écrit :
This would mean that the loop variable could practically not be used outside of the for loop. If this is really true, I'd really favour a syntax that makes this clear (like `for i : Integer = 1 to 10 do ...'), so i has only the corresponding scope.
In fact this very syntax was used in one of the intermediate Wirth languages between algol and pascal (we used at Grenoble an algolW compiler implementing it at that time). It was done so exactly to forbid any use of the for control variable outside of the loop, because in many CPU for control variables are maintained in registers (CX in 16 bit 386 CPU for example) and need not at any time to be affected into memory (at least the for control variable of the innermost loop). So a good idea was lost in going into EP. But who may update the standard ? Maurice
On 21 May 2000, at 22:01, Frank Heckenbach wrote:
I believe that says that you can't modify the control variable of a for- statement (a "threat" is defined in the standard as one of ten ways that a variable may be assigned a value).
Including a `for' statement (item g :-). Therefore I conclude that a `for' statement by itself is illegal in Pascal.
Nearly. ;-) I believe item "g" actually refers to this case:
for i := 1 to 10 do for i := 11 to 20 do ;
The second for-statement is contained in the first and threatens the first for-statement's control variable, and so is illegal by item "g".
Alright, we'll take it out of the next GPC release.
I agree that it might be easier to do this than to try to understand the EP standard!
Yes, but is a goto into a loop legal at all (the last sentence of 6.9.2.4 seems to indicate not to me, but I'm not completely sure)?
The last sentence of 6.9.2.4 says:
"It shall be a dynamic-violation if the commencement of the activation containing the program-point has not been completed (see 6.2.3.8)."
But a for-statement does not appear to be an activation. 6.2.3.2 refers to activations of "a block or a module...." A for-statement is not a block and it is not a module (it's a structured-statement).
However, on additional inspection, it appears that a goto into a loop is not legal by 6.9.1:
"A label, if any, of a statement S shall be designated as prefixing S. The label shall be permitted to occur in a goto-statement G (see 6.9.2.4) if and only if any of the following three conditions is satisfied:
(a) S contains G.
(b) S is a statement of a statement-sequence containing G.
(c) S is a statement of the statement-sequence of the compound-statement of the statement-part of a block containing G."
Item "b" appears to be the key, as the question fails items "a" and "c". Going out of a for-statement is legal:
for i := 1 to 10 do goto 1; 1: ;
...because the for-statement (part of the statement-sequence containing G) and the null-statement (S) are both part of the same statement-sequence. However, going into a for-statement is not legal:
goto 1; for i := 1 to 10 do 1: ;
...because the null-statement (S) is not part of the statement-sequence containing the goto-statement (the statement-sequence containing the goto- statement consists of the goto-statement and the for-statement but *not* the null-statement).
It took me three days of head-scratching to decide this, so I hope I am correct (this time)!
This would mean that the loop variable could practically not be used outside of the for loop.
Except in the specific case where the for-statement was exited by a goto (6.9.3.9.1, "After a for-statement is executed, other than being left by a goto-statement, the control-variable shall be undefined."). In this case, the value is valid and usable, so you wouldn't want to limit the scope to just the for-statement.
My original wrong comment was that you couldn't *assign* to the control- variable outside of the loop, although you could still read it. However, as Marco van de Voort showed, I was in error.
My head hurts! ;-)
-- Dave