# Checking properties of the compiler and the run-time environment

chksys.f | A program to determine the properties of the run-time environment for FORTRAN 77 programs
chkcomp.f | A FORTRAN 77 source file containing deliberate deviations from the standard and deliberate bad statements for testing the compiler's accuracy
chksysff.f90 | A program to determine the properties of the run-time environment for Fortran 90 programs
chkcomff.f90 | A Fortran 90 source file containing deliberate deviations from the standard and deliberate bad statements for testing the compiler's accuracy
chksysc.c | A program to determine the properties of the run-time environment for C programs
chkcompc.c | A C source file containing deliberate deviations from the standard and deliberate bad statements for testing the compiler's accuracy
fp_special.f90 | A Fortran 90 program to test the behaviour of a program in the presence of floating-point exceptions and special IEEE numbers (notably negative zeros)

### Introduction

The programs CHKSYS and CHKSYSFF are meant to help understand the run-time environment of a FORTRAN program. For C there is a similar program, CHKSYSC.

In many cases the actual behaviour of a program depends on the compiler you use and the options you included during the compile and link steps. This is especially true if errors occur or if you are using certain open-ended language features.

Many programmers are not aware that such features exist and it is sometimes difficult or impossible to find them in the documentation.

That is where the CHKSYS offer some assistence:

- It checks areas that are open-ended, such as whether local variables are automatically saved between subroutine calls and various odd errors that can occur when using external files.
- It checks how (deliberate) run-time errors are handled, such as an overflow or an exceedance of array bounds.

The program source CHKCOMP (in chkcomp.f(or) and its Fortran 90 equivalent chkcomff.f90) is meant to test the accuracy of the compiler. It is not meant to validate the compiler. It simply contains a fair number of very common extensions to the standard and some deliberate program errors (like jumping into a DO-loop and inaccessible statements). The errors are documented in the source code via comments.

The rest of this document describes:
How to use the programs
Description of the tests
Presentation of some results

### Usage of the programs

CHKCOMP:

- First run the compiler of choice with standard options
- Then try to find out what extra options are needed to get the maximum set of messages. Such options include:
  - Highest warning level
  - Check strict conformance to standard
  - Check interfaces
  - etc.
- In general, it is a good idea to ALWAYS ask for the maximum number of checks, as this can prevent programming errors at an early stage.
- Some (or many) compilers are lazy: they will offer very little checks beyond basic syntax. Shun such compilers - or at least use appropriate program checkers beside them.

CHKSYS:

- Compile the program with the same options as the CHKCOMP source. If this would result in errors, remove the strict conformance to the standard, as it uses one, common, extension: IMPLICIT NONE.
- Run the program once to get the general features of the run-time environment
- Edit the file "chksys.set" to select the more disruptive tests.
- Study the source code and the file "chksys.msg" to see how things are done. You might learn something from it or you might have suggestions.
- Use various compiler options:
  - With and without optimisations
  - Array bounds checking
  - Strict conformance to the standard
  - Numerical options (like treatment of overflows and underflows)

### Tests that are performed

CHKSYS performs the following tests:

- Operating system:
  - What type of system (UNIX, MS-DOS/Windows 3.x or Windows 95/NT)?
  - Support for long file names?
  - Distinction between upper and lower case in file names?
- Memory model:
  - Static (local variables are automatically saved) or dynamic (you must use SAVE to save the values)
  - Length of an integer:
    - 2 or 4 bytes? Often selectable via compiler switch. Determines range
  - Precision of real variables and numerical operations:
    - How many decimals are significant?
    - Any obvious problems with multiplications
  - What is the unit for the length of a direct-access record?
    - Often a byte, sometimes a word (e.g. 4 bytes!)
  - Are binary files allowed? And what keywords do you use?
  - How many files can be opened at the same time?
  - File handling:
    - Are the parameters to the OPEN statement checked immediately?
    - Using unformatted READs on a formatted file
    - Writing to an unopened file
    - Reading too many data from a record of an unformatted file
    - Writing too many data to a record of a direct-access file
    - Opening the same file twice
    - Closing an unopened file
    - Opening a second file to the same unit
    - Reading files of which the last line is incomplete
  - Check the behaviour of DO-loops:
    - Can you change the value of a DO-variable?
    - What happens if you change the upper limit?
    - Are DO-loops performed at least once? (They should not!)
  - Check the behaviour of overlapping substrings:
    - Shifting characters to the left and right
  - Miscellaneous stuff:
    - Treatment of a backslash (C-like espace character?)
    - Formatting in list-directed output
    - The first character when writing to the screen

  ### Some results

  Compiling CHKCOMP:

  The first listing is the result when using MicroSoft FORTRAN version 5.1, with the maximum level of warnings (which turns out to be the default) but not the switch to force checking against the standard:

      chkcomp.for(79) : error F2566: INTEGER : REAL : type conversion error
      chkcomp.for(80) : error F2566: INTEGER : REAL : type conversion error
      chkcomp.for(81) : error F2005: illegal REAL constant
      chkcomp.for(82) : error F2566: REAL : REAL : type conversion error
      chkcomp.for(128) : error F2516: I : assignment using active DO variable illegal
      chkcomp.for(136) : warning F4801: label 120 : used across blocks
      chkcomp.for(141) : warning F4801: label 130 : used across blocks
      chkcomp.for(171) : warning F4999: LOWCAS : variable declared but not used
      chkcomp.for(171) : warning F4999: LONGVARIABLENAME : variable declared but not used
      chkcomp.for(171) : warning F4999: UND_SC : variable declared but not used
      chkcomp.for(171) : warning F4999: INT2 : variable declared but not used
      chkcomp.for(171) : warning F4999: INT4 : variable declared but not used
      chkcomp.for(171) : warning F4999: INTV2 : variable declared but not used
      chkcomp.for(171) : warning F4999: DBLVAL : variable declared but not used
      chkcomp.for(171) : warning F4999: REAVAL : variable declared but not used
      chkcomp.for(178) : error F3606: SUBR1 : formal argument REAVAL : type mismatch
      chkcomp.for(187) : error F2202: SUBR2 : defined with different number of arguments

  Below is a listing from the Lahey FORTRAN 77 compiler, version 5.20, using no particular switches:

      Compiling chkcomp.for, a Standard Format Source File

      OPTION  DESCRIPTION                    OPTION  DESCRIPTION
      /n0  - Standard FORTRAN 77 IMPLICIT    /nL  - No Line-number table
      /n2  - Generate 387 constants and code / P  - Protect constant arguments
      /n4  - No 80486 optimizations          /nQ1 - "Unlimited" NDP stack
      /n7  - Optimize inter-statement        /nQ2 - No protected-mode RPC
      /nA2 - No allocatable array checking   /nQ3 - No real-mode RPC
      /nB  - No Bounds checking              / R  - Remember local variables
      /nC  - Ignore nonstandard usage        / S  - Create filename.SLD for SOLD
      /nC1 - INTEGER constants 4 bytes       /nT  - INTEGER*4, LOGICAL*4 default
      /nD  - DIRECT files with headers       /nV  - Not VAX interpretation
      /nH  - No Hardcopy source listing      / W  - Display Warning messages
      /nI  - No Interface checking           /nX  - No Xref listing
      /nK  - Generate 80x87 code             /nZ1 - Better SOLD debugging

      Compiling line 35:       PROGRAM CHKCMP
      File chkcomp.for, line 80:
            INTVAL = 1.0E20
                          ^
      Warning - INTEGER variable (INTVAL) possibly assigned new value before
      former value used.

      File chkcomp.for, line 81:
            REAVAL = 1.0E100
                           ^
      Fatal - Expression is not within numeric limits of REAL data type
      (1.18E-38 : 3.40E+38) (See Section 6.3 in Lahey Programmer's Reference).

      File chkcomp.for, line 82:
            REAVAL = 1.0D100
                           ^
      Warning - REAL variable (REAVAL) possibly assigned new value before former
      value used.

      File chkcomp.for, line 84:
            REAVAL = DBLVAL
                          ^
      Warning - REAL variable (REAVAL) possibly assigned new value before former
      value used.

      File chkcomp.for, line 90:
            INTVAL = LEN(STRING) + 1
                                   ^
      Warning - INTEGER variable (INTVAL) possibly assigned new value before
      former value used.

      File chkcomp.for, line 121:
            INTVAL = INTV2
                         ^
      Warning - INTEGER variable (INTV2) is used before being assigned a value.

      File chkcomp.for, line 128:
               IF ( I      .EQ. 5 ) I      = 6
                                             ^^
      Fatal - INTEGER variable (I) is a DO index, cannot assign a value (See
      Section 8.4.1 in Lahey Language Reference).
      Fatal - Statement illegal as IF suffix (See Section 8.5.2.2 in Lahey
      Language Reference).

      File chkcomp.for, line 148:
            WRITE(*,*) 'This statement is not reachable'
                                                        ^
      Warning - No execution path reaches this statement.

      File chkcomp.for, line 156:
            WRITE(*,*) 'Neither is this'
                                        ^
      Warning - No execution path reaches this statement.

      Warning - INTEGER variable (LOWCAS) is declared but never used,
      File chkcomp.for, line 58.
      Warning - INTEGER variable (UND_SC) is declared but never used,
      File chkcomp.for, line 59.
      Warning - INTEGER variable (LONGVARIABLENAME) is declared but never used,
      File chkcomp.for, line 60.
      Warning - INTEGER variable (INT4) is declared but never used,
      File chkcomp.for, line 61.
      Warning - INTEGER*2 variable (INT2) is declared but never used,
      File chkcomp.for, line 62.

      Fatal - Expression is not within numeric limits of INTEGER data type
      (-2,147,483,648 : 2,147,483,647) (See Section 6.3 in Lahey Programmer's
      Reference), File chkcomp.for, line 79.
      Fatal - Expression is not within numeric limits of INTEGER data type
      (-2,147,483,648 : 2,147,483,647) (See Section 6.3 in Lahey Programmer's
      Reference), File chkcomp.for, line 80.
      Warning - REAL variable (REAVAL) assigned a value, never used,
      File chkcomp.for, lines 81, 82, 84.
      Fatal - Expression is not within numeric limits of REAL data type
      (1.18E-38 : 3.40E+38) (See Section 6.3 in Lahey Programmer's Reference),
      File chkcomp.for, line 82.
      Fatal - Substring specifier must be > 0 and <= string length (See Section
      4.4.4.1 in Lahey Language Reference), File chkcomp.for, line 89.
      Fatal - Statement label (120) appears in transfer context outside DO range
      or block IF (See Chapter 8 in Lahey Language Reference), File chkcomp.for,
       line 132.
      Fatal - Statement label (130) appears in transfer context outside DO range
      or block IF (See Chapter 8 in Lahey Language Reference), File chkcomp.for,
       line 133.

      Compiling line 173:       SUBROUTINE SUBR1(  REAVAL )
      Compiling line 182:       SUBROUTINE SUBR2(  INTVAL )
      File chkcomp.for, line 182:
            SUBROUTINE SUBR2(  INTVAL )
                                      ^
      Warning - Argument count conflicts with previous usage (See Section 10.3.1
      in Lahey Language Reference).

      Compiling line 191:       SUBROUTINE PDEBUG
      File chkcomp.for, line 201:
      D     WRITE(*,*) 'In DEBUG mode'

      Abort - Standard source file, columns 1-5: blanks and/or digits (See
      Section 1.6 in Lahey Language Reference).

  Both compilers are fairly old (copyrights indicate 1992), but they do show the capabilities of a good compiler:
  - Interface checks:
    - These are a major source of errors and unfortunately FORTRAN 77 provides no prototyping mechanisms. The compilers check the consistency within the file only.
  - Use and misuse of variables:
    - Both warn about variables that have been declared, but not been used.
    - The Lahey compiler does a more thorough job, because it also warns about new assignments before the previous value was used.
    - Illegal use of DO-loop variables.
  - Unreachable statements:
    - The MicroSoft compiler does not warn us about them
    - The Lahey compiler does a pretty thorough job! It even detects the problem with this construct:

          151      IF ( INTVAL .GT. 10 ) THEN
          152         GOTO 220
          153      ELSE
          154         GOTO 230
          155      ENDIF
          156      WRITE(*,*) 'Neither is this'

    - Illegal substrings:
      - Note the fatal error for line 89: we are using a zero-length substring.