Skip to main content
Thomas Perry, here... Changes provide corrections regarding the availability of DEFINE in the Lahey compiler for Fortran 77.
Source Link

Examination of documentation for two other versions of Fortran 77 shows this feature is recognized as unrecognizeda Fortran 77 feature in Lahey Fortran, 1994, but recognizedand also recognized in Microsoft Fortran 5.0/5.1 1991, the predecessor of Compaq Fortran mentioned below. The Lahey unavailability may likely be due to memory protection issues necessary for the operating-system environments of non-mainframe systems.

Examination of documentation for two other versions of Fortran 77 shows this feature as unrecognized in Lahey Fortran, 1994, but recognized in Microsoft Fortran 5.0/5.1 1991, the predecessor of Compaq Fortran mentioned below. The Lahey unavailability may likely be due to memory protection issues necessary for the operating-system environments of non-mainframe systems.

Examination of documentation for two other versions of Fortran 77 shows this feature is recognized as a Fortran 77 feature in Lahey Fortran, 1994, and also recognized in Microsoft Fortran 5.0/5.1 1991, the predecessor of Compaq Fortran mentioned below. The Lahey unavailability may likely be due to memory protection issues necessary for the operating-system environments of non-mainframe systems.

Source Link

This discussion is in support of the previous answers. Hopefully, this is not the answer to some other question that was not asked. The question was in reference to passing values without restriction in old compilers, but no reference was given to how old. So lets start at the time of really old. This appears to be a non-standard feature used in Univac Fortran V (ca. 1973), and and also in Univac ASCII Fortran (ca. 1982). The implementation of Univac Fortran V on the 1100 mainframe system, is the predecessor of Univac ASCII Fortran, and predominantly set the standard for Fortran 77. Univac ASCII Fortran was the full version of Fortran 77 implemented on Univac 1108 system.

The feature mentioned in the question is very similar to the DEFINE statement in Univac Fortran V. Lets think a minute... Here we are writing a main program and several subprograms called by the main program. The nature of features like DEFINE was to allow control at the head of the main program, before stepping into execution, to set the values or name references of constants, variables and functions that were seen by the executable area of the main program and its subprograms. There were conflict restrictions the programmer had to consider in selecting variable naming conventions for the main program and subprograms, but DEFINE voided that restriction, but only for those constants, variables, and functions set by DEFINE. This gave the ability of the programmer to have program global control of DEFINE features to all areas of the program without passing arguments. Constants, variables, and functions set by DEFINE had unrestricted naming conventions. This was, at times, indispensable. This meant the programmer could set the value of a constant or variable without restriction, or DEFINE a function this way, and could access these defined features anywhere in the executable's environment. These features were defined after setting the type but before the first executable in the main program. The highly proscriptive programming, compilation, and execution environment on the Univac system prevented the modification of memory areas outside of that allocated to the program by the compiler and executive operating system, a protective memory addressing issue. An attempted write-protection violation was a very serious issue. DEFINE allowed a modification of this but only after the non-executable type-setting area of the program, before the executable section of the program. This is consistent with the stated address passing action mentioned in the question.

Here is an example -

       DEFINE F(X,Y) = X + Y        a type definition of a function

followed by

       A = F(U*V,V)         results in A = U*V + V where A,U,V are *real*

or, for example

       D = F(I*J,K*I)   I,J,K are double precision, D is double precision by propagation

resulting in

       D = I*J + K*I     a double precision expression...

(Pretty cool! Especially if one does not have to mess with naming restrictions!!)

Univac Fortran V documentation states the following...

4.2 DEFINE PROCEEDURES
A DEFINE generates inline code when it is referenced. Thus, it is analogous to an 1108 assembly procedure, rather than to an external or internal FUNCTION, which generates a closed subprogram. The overhead of a subprogram is eliminated and the optimization capabilities of the compiler are allowed to operate. The FORTRAN IV arithmetic statement functions are a subset of the DEFINE procedure.

Univac ASCII Fortran documentation shows the definition is little changed and gives the following characterization...

The statement function generates inline code when it is referenced. This allows efficient references to the defining expression without referencing the expression each time.

In other words, DEFINE(expression) is a statement function definition that is global (i.e. unrestricted) within the allocated program environment. This would be extremely useful.

Examination of documentation for two other versions of Fortran 77 shows this feature as unrecognized in Lahey Fortran, 1994, but recognized in Microsoft Fortran 5.0/5.1 1991, the predecessor of Compaq Fortran mentioned below. The Lahey unavailability may likely be due to memory protection issues necessary for the operating-system environments of non-mainframe systems.

Examination of documentation for Compaq Fortran version 6.6A (May 2002), the industry standard pc-implementation of VAX Fortran 77 at the time, showed the feature is recognized as non-standard and operates in very much the same way mentioned in the question.

The following is noted -

15.1.5 DEFINE and UNDEFINE Directives -
The DEFINE directive creates a symbolic variable whose existence or value can be tested during conditional compilation. The UNDEFINE directive removes a defined symbol.
...
Rules and Behavior -
DEFINE and UNDEFINE create and remove variables for use with the IF (or IF DEFINED) directive. Symbols defined with the DEFINE directive are local to the directive. They cannot be declared in the Fortran Program.
Because Fortran programs cannot access the named variables, the names can duplicate Fortran keywords, intrinsic functions, or user-defined names without conflict. To test whether a symbol has been defined, use the IF DEFINED (name) directive. You can assign an integer value to a defined symbol. To test the assigned value of name, use the IF directive. IF test expressions can contain most logical and arithmetic operators.
Attempting to undefine a symbol that has not be defined produces a compiler warning.
The DEFINE and UNDEFINE directives can appear anywhere in a program enabling and disabling symbol definitions.
Examples - Consider the following

   |DEC$ DEFINE  testflag  
   |DEC$ IF DEFINED (testflag)  
       WRITE( * , * ) 'Compiling first line'
etc...

In the above example, IF DEFINED (testflag) is true, Compiling first line will be written.

The following documentation may be of interest...

Univac 1100 Series Fortran V Programmer Reference, UP-4060 Rev. 2, 1973

Sperry Univac Series 1100 Fortran (ASCII) Level 10-R1 Programmer Reference, UP-8244.2, 1982

Compaq Fortran Language Reference Manual, Order Number: AA-Q66SD-TK, September 1999

Compaq Fortran is now Intel Fortran.

So we went from really old, to maybe not so old. Hope this answer was of some help...