j***@usm.edu
2018-05-22 22:18:02 UTC
Hello!
I'm playing with Oberon-07 using the obnc and oberonc compilers (which are great BTW). Today I hit on a surprise: I was sure that Oberon’s FOR loop behaved like that of Pascal, Modula-2, and Ada. That is, I thought the following should print the numbers from 1 to 20:
i := 20;
FOR j := 1 TO i DO
Out.Int(j, 0); Out.Ln;
i := i - 1;
END;
This is admittedly dumb code, but never mind that. I just checked this with freepascal, Gnu Modula-2, and gnat, and all three produce code that prints all the numbers from 1 to 20. I guess this is because the value of i is evaluated at the beginning of the loop, then stored for future tests. This can be more efficient in general, especially if the test involves a complicated function.
In C, on the other hand,it prints the numbers from 1 to 10, because C would evaluate the value of i on each pass through the loop.
It turns out that in code produced by obnc and oberonc, the FOR loop behaves like C, and NOT like the other Pascal-derived languages I mentioned.
I was sure this was a bug: why would Wirth change the semantics of a FOR loop? I went to look in “Programming in Oberon,” and the semantics are explained on p. 21:
It is recommended that the for statement be used in simple cases only;
in particular, no components of the expressions determining the range
must be affected by the repeated statements, and, above all, the
control variable itself must not be changed by the repeated statements.
The value of the control variable must be considered as undefined after
the for statement is terminated.
Again, I concede that the loop above is bad code. Still, I’m curious:
1) Is it an error, because I modify i, violating “no components of the expressions determining the range must be affected”?
2) If so, should the compiler report an error?
3) If not, should the compiler produce code similar to Pascal et al., or identical to C?
I realize there's a workaround. I just want to know what the language lawyers think of it.
sincerely
john perry
I'm playing with Oberon-07 using the obnc and oberonc compilers (which are great BTW). Today I hit on a surprise: I was sure that Oberon’s FOR loop behaved like that of Pascal, Modula-2, and Ada. That is, I thought the following should print the numbers from 1 to 20:
i := 20;
FOR j := 1 TO i DO
Out.Int(j, 0); Out.Ln;
i := i - 1;
END;
This is admittedly dumb code, but never mind that. I just checked this with freepascal, Gnu Modula-2, and gnat, and all three produce code that prints all the numbers from 1 to 20. I guess this is because the value of i is evaluated at the beginning of the loop, then stored for future tests. This can be more efficient in general, especially if the test involves a complicated function.
In C, on the other hand,it prints the numbers from 1 to 10, because C would evaluate the value of i on each pass through the loop.
It turns out that in code produced by obnc and oberonc, the FOR loop behaves like C, and NOT like the other Pascal-derived languages I mentioned.
I was sure this was a bug: why would Wirth change the semantics of a FOR loop? I went to look in “Programming in Oberon,” and the semantics are explained on p. 21:
It is recommended that the for statement be used in simple cases only;
in particular, no components of the expressions determining the range
must be affected by the repeated statements, and, above all, the
control variable itself must not be changed by the repeated statements.
The value of the control variable must be considered as undefined after
the for statement is terminated.
Again, I concede that the loop above is bad code. Still, I’m curious:
1) Is it an error, because I modify i, violating “no components of the expressions determining the range must be affected”?
2) If so, should the compiler report an error?
3) If not, should the compiler produce code similar to Pascal et al., or identical to C?
I realize there's a workaround. I just want to know what the language lawyers think of it.
sincerely
john perry