The attached program demonstrates an issue with Gnu Pascal, version 20030507. The program cannot be compiled because of a non-existent "threat" on the global loop variable used in a subroutine. The main program has a loop which uses the variable, but calls no subroutines within the loop, and therefore is not vulnerable to any threat from use of that variable by other subroutines.
Attempting to compile this program results in the message
gpc -o forwarning forwarning.pas forwarning.pas: In main program: forwarning.pas:13: error: `for' loop counter is threatened in a subroutine
This usage is present in Donald E. Knuth's WEB and TeX programs, and requires changing these loops to use unique loop variables.
If there is a way to disable this check, I cannot find it in the documentation.
gpc --version results in:
Reading specs from /Developer/Pascal/gpc33d6/lib/gcc-lib/powerpc-apple-darwin/3.3/specs Configured with: ../gpc-3.3d6/configure --enable-languages=pascal,c --enable-threads=posix --prefix=/Developer/Pascal/gpc33d6 --target=powerpc-apple-darwin Thread model: posix gpc version 20030507, based on gcc-3.3
Thank you for your help.
--Joe Oswald
Joseph Oswald wrote:
The attached program demonstrates an issue with Gnu Pascal, version 20030507. The program cannot be compiled because of a non-existent "threat" on the global loop variable used in a subroutine. The main program has a loop which uses the variable, but calls no subroutines within the loop, and therefore is not vulnerable to any threat from use of that variable by other subroutines.
Attempting to compile this program results in the message
gpc -o forwarning forwarning.pas forwarning.pas: In main program: forwarning.pas:13: error: `for' loop counter is threatened in a subroutine
The program contains an error involving a for loop and when fixed GPC compiles the program with no errors. The above error message, though, is pretty misleading as to real error in the program.
Both Pascal standards specify the following requirement for for-statements:
"The control-variable shall be an entire-variable whose identifier is declared in a variable-declaration- part of the block closest-containing the for-statement."
Thus the useloopvar subroutine as written is an illegal code construct since there is no declaration for the loopvar control variable in the useloopvar block which closest-contains the for-statement..
procedure useloopvar; {ERROR - no local var declaration for loopvar} begin for loopvar := 1 to 3 do writeln('useloopvar ',loopvar) end; { useloopvar }
The fix is to add a local var declaration for loopvar:
procedure useloopvar; var loopvar: integer; begin for loopvar := 1 to 3 do writeln('useloopvar ',loopvar) end; { useloopvar }
With the above add local var declaration, the program compiles, runs, and produces the expected out.
This usage is present in Donald E. Knuth's WEB and TeX programs, and requires changing these loops to use unique loop variables.
This isn't the first time nor will it be the last time when porting a program to a different compiler uncovers latent errors in a program. In the area of for-statements, there are latent errors in quite a few programs since there are quite a few compilers around which don't enforce all the for-statement requirements.
Gale Paeper gpaeper@empirenet.com
Gale Paeper wrote:
Joseph Oswald wrote:
The attached program demonstrates an issue with Gnu Pascal, version 20030507. The program cannot be compiled because of a non-existent "threat" on the global loop variable used in a subroutine. The main program has a loop which uses the variable, but calls no subroutines within the loop, and therefore is not vulnerable to any threat from use of that variable by other subroutines.
Attempting to compile this program results in the message
gpc -o forwarning forwarning.pas forwarning.pas: In main program: forwarning.pas:13: error: `for' loop counter is threatened in a subroutine
The program contains an error involving a for loop and when fixed GPC compiles the program with no errors. The above error message, though, is pretty misleading as to real error in the program.
Both Pascal standards specify the following requirement for for-statements:
"The control-variable shall be an entire-variable whose identifier is declared in a variable-declaration- part of the block closest-containing the for-statement."
That's another error, at least in the test program, which GPC detects with `--classic-pascal' or `--extended-pascal'.
However, AFAICS, also the error message above is correct since it's not necessary to call the routine for the error to appear:
: 6.9.3.9 ForÂstatements : : 6.9.3.9.1 General : : 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.
In the test program, if in useloopvar you replace the loop with a simple assignment to loopvar, you have this error without the first one.
This usage is present in Donald E. Knuth's WEB and TeX programs, and requires changing these loops to use unique loop variables.
If there is a way to disable this check, I cannot find it in the documentation.
Currently `--borland-pascal' or `--delphi' will turn it into a warning only (though `--borland-pascal' is probably not really the best dialect to compile TeX, it actually doesn't seem to cause more problems at first glance).
This isn't the first time nor will it be the last time when porting a program to a different compiler uncovers latent errors in a program.
I tried to compile Web and TeX and noticed a few more problems, though apparently all quite minor:
- Compiler directives `{$C-,A+,D-}'
- `WriteLn' applied to `packed file of Char' rather than `Text'
- `others:' instead of `otherwise'
- `Break (FileVar)' (perhaps the same as `Page'?)
- 3rd parameter to `Reset' and `Rewrite'
- hard-coded 'TTY:' for terminal (VMS specific?; Unix has '/dev/tty', Dos 'con')
- `erstat (FileVar)' (perhaps the same as BP's `IOResult' with `{$I-}')
- `breakin (FileVar)' (input flushing?)
- a lot of warnings which all seem to be harmless, but point to unniceties in the code
Time for `--dec-pascal' ...?
In the area of for-statements, there are latent errors in quite a few programs since there are quite a few compilers around which don't enforce all the for-statement requirements.
Seems quite so. (GPC does one or two more now, but still not all.)
Frank
Frank Heckenbach wrote:
Gale Paeper wrote:
Joseph Oswald wrote:
The attached program demonstrates an issue with Gnu Pascal, version 20030507. The program cannot be compiled because of a non-existent "threat" on the global loop variable used in a subroutine. The main program has a loop which uses the variable, but calls no subroutines within the loop, and therefore is not vulnerable to any threat from use of that variable by other subroutines.
Attempting to compile this program results in the message
gpc -o forwarning forwarning.pas forwarning.pas: In main program: forwarning.pas:13: error: `for' loop counter is threatened in a subroutine
The program contains an error involving a for loop and when fixed GPC compiles the program with no errors. The above error message, though, is pretty misleading as to real error in the program.
Both Pascal standards specify the following requirement for for-statements:
"The control-variable shall be an entire-variable whose identifier is declared in a variable-declaration- part of the block closest-containing the for-statement."
That's another error, at least in the test program, which GPC detects with `--classic-pascal' or `--extended-pascal'.
Since my previous posting, I dug into the compiler source code and saw where GPC supports a Borland extension which relaxes the requirement.
However, AFAICS, also the error message above is correct since it's not necessary to call the routine for the error to appear:
: 6.9.3.9 Forstatements : : 6.9.3.9.1 General : : Neither : a forstatement nor any procedureand functiondeclarationpart of the : block that closestcontains a forstatement shall contain a statement : threatening (see 6.9.4) a variableaccess denoting the variable denoted by : the controlvariable of the forstatement.
In the test program, if in useloopvar you replace the loop with a simple assignment to loopvar, you have this error without the first one.
After seeing the Borland extension support, I had though of that variation but didn't get around to testing it.
This has helped clarify my understanding of controlvariable threat requirements. For some reason or other, I've never picked up the full implications of the "any procedureandfunctiondeclarationpart" part of the requirement. For-statement threat requirements is one area a lot of compilers don't even attempt to enforce. So one ends up adopting coding practices which avoids the ills the threat requirements are designed to preclude anyway.
[snip]
I tried to compile Web and TeX and noticed a few more problems, though apparently all quite minor:
Compiler directives `{$C-,A+,D-}'
`WriteLn' applied to `packed file of Char' rather than `Text'
`others:' instead of `otherwise'
`Break (FileVar)' (perhaps the same as `Page'?)
3rd parameter to `Reset' and `Rewrite'
hard-coded 'TTY:' for terminal (VMS specific?; Unix has '/dev/tty', Dos 'con')
`erstat (FileVar)' (perhaps the same as BP's `IOResult' with `{$I-}')
`breakin (FileVar)' (input flushing?)
a lot of warnings which all seem to be harmless, but point to unniceties in the code
Time for `--dec-pascal' ...?
Perhaps not. With some 'net seaching, I found a location with a set of "master files personally by Donald E. Knuth" at ftp://ctan.tug.org/tex-archive/systems/knuth/. In that file set, there are change files with comments like "Change file for GNU Pascal and Linux". Never having worked with Web and TeX code before, I don't know how much help those files will be in fixing the problems but it does seem to have a some promising potential.
Gale Paeper gpaeper@empirenet.com
On Sun, Jul 27, 2003 at 03:33:00PM +0200, Frank Heckenbach wrote: [...]
I tried to compile Web and TeX and noticed a few more problems, though apparently all quite minor:
Compiler directives `{$C-,A+,D-}'
`WriteLn' applied to `packed file of Char' rather than `Text'
`others:' instead of `otherwise'
`Break (FileVar)' (perhaps the same as `Page'?)
No, it should flush the output buffer. AFAIK it is redundant in the current GPC I/O implementation.
3rd parameter to `Reset' and `Rewrite'
hard-coded 'TTY:' for terminal (VMS specific?; Unix has '/dev/tty', Dos 'con')
`erstat (FileVar)' (perhaps the same as BP's `IOResult' with `{$I-}')
`breakin (FileVar)' (input flushing?)
a lot of warnings which all seem to be harmless, but point to unniceties in the code
Most of these are not unniceties, but results of heavy WEB macro usage and Knuth's coding style. In particular, `if <.....> then do_nothing;' is a common idiom to ignore a function result using Pascal's standard syntax (`do_nothing' is a macro with empty expansion).
Some more subtle (but important) differencies:
- `packed file of 0..255' doesn't actually pack anything in GPC, hence the definition of `eight_bits' has to be changed to `byte'
- the code assumes non-lazy I/O. The `bypass_eoln' stuff in `input_ln' is a work around for this problem, and it has to be removed for GPC
Anyway, I have a functional GPC port of TeX (with some extra hacks). If anybody is interested in the change file, I can send it by email. Disclaimer: it is _not_ intended as a standalone production version: e.g., it is TeX only (no MF/tangle/dvitype/etc.), and it relies on Web2C's libkpathsea for path searching. (IMHO, developing a yet-another full TeX implementation which aims for everyday use is a _wrong_ idea, because it would be a major duplication of effort, wasting time and money. If anybody wants to do that, it would be much better to join the Web2C team.)
Emil