Compaq Fortran
User Manual for
Tru64 UNIX and Linux Alpha Systems


Previous Contents Index

11.1.8 Argument-Passing Mechanisms and Built-In Functions

When a Compaq Fortran program needs to call a routine written in a different language (or in some cases a Fortran subprogram), there may be a need to use a form other the Compaq Fortran default passing mechanisms. For example, numeric arguments may need to be passed by immediate value instead of by reference.

To change the Compaq Fortran default mechanisms with the Compaq Fortran built-in functions, use the following functions:

The %VAL or %REF functions can only be used as unparenthesized arguments in actual argument lists.

Instead of the Compaq Fortran built-in functions, you can use the cDEC$ ATTRIBUTES directive to change the Compaq Fortran default passing mechanisms for either an entire call or for individual arguments. (See Section 11.2.2).

11.1.8.1 Passing Addresses --- %LOC Function

The %LOC built-in function computes the address of a storage element as an INTEGER*8 (Alpha UNIX systems) value. You can then use this value in an arithmetic expression. It has the following form:

%LOC(arg)

The %LOC function is particularly useful for non-Fortran procedures that may require argument data structures containing the addresses of storage elements. In such cases, the data structures should be declared volatile to protect them from possible optimizations.

For More Information:

11.1.8.2 Passing Arguments by Immediate Value --- %VAL Function

The %VAL function passes the argument list entry as a 64-bit immediate value on Compaq Tru64 UNIX and Linux systems. It has the following form:

%VAL(arg)

The argument-list entry generated by the compiler is the value of the argument (arg). Because argument-list entries are eight bytes long, the argument value must be an INTEGER (including INTEGER*8), LOGICAL (including LOGICAL*8), or REAL (REAL*4 and REAL*8) constant, variable, array element, or expression.

If a COMPLEX (KIND=4) or COMPLEX (KIND=8) argument is passed by value, two REAL arguments (one contains the real part; the other the imaginary part) are passed by immediate value. If a COMPLEX parameter to a routine is specified as received by value (or given the C attribute), two REAL parameters are received and stored in the real and imaginary parts of the COMPLEX parameter specified. COMPLEX*32 arguments cannot be passed by value.

If the value is a byte, word, or longword, it is sign-extended to eight bytes.

To produce a zero-extended value rather than a sign-extended value, use the ZEXT intrinsic function (see the Compaq Fortran Language Reference Manual).

11.1.8.3 Passing Arguments by Reference --- %REF Function

The %REF function passes the argument by reference. It has the following form:

%REF(arg)

The argument-list entry the compiler generates will contain the address of the argument, (arg). The argument value can be a record name, a procedure name, or a numeric or character expression, array, character array section, or array element. In Compaq Fortran, passing by reference is the default mechanism for numeric values, so the %REF call is usually not needed. Passing character arrays with %REF caused the hidden length to be omitted.

11.1.8.4 Examples of Argument Passing Built-in Functions

The following examples show the use of the argument list built-in functions:

For an example of passing integer data by value (using %VAL) and by reference (default) to a C function, see Section 11.4.7.

11.2 Using the cDEC$ ALIAS and cDEC$ ATTRIBUTES Directives

This section provides reference information about the following directives:

11.2.1 The cDEC$ ALIAS directive

Compaq Fortran supports the cDEC$ ALIAS directive in the same manner as Compaq Fortran 77. Use this directive to specify that the external name of an external subprogram is different from the name by which the calling procedure references it.

The syntax is:

cDEC$ ALIAS internal-name, external-name

The internal-name is the name of the subprogram as used in the current program unit.

The external-name is either a quoted character constant (delimited by single quotation marks) or a symbolic name.

If external-name is a quoted character constant, the value of that constant is used as the external name for the specified internal name. The character constant is used as it appears, with no modifications for case or addition or removal of punctuation characters. The default for the Compaq Fortran compiler is to force the name into lowercase and append an underscore unless directed otherwise.

If external-name is a symbolic name, the symbolic name (in lowercase) is used as the external name for the specified internal name and an underscore is appended. Any other declaration of the specified symbolic name is ignored for the purposes of the ALIAS directive.

The Compaq Tru64 UNIX and Linux linker may have restrictions on what appears in an external name and whether external names are case sensitive.

For example, in the following program (free source form):


  PROGRAM ALIAS_EXAMPLE 
  !DEC$ ALIAS ROUT1, 'ROUT1A' 
  !DEC$ ALIAS ROUT2, 'routine2_' 
  !DEC$ ALIAS ROUT3, rout3A 
        CALL ROUT1 
        CALL ROUT2 
        CALL ROUT3 
  END PROGRAM ALIAS_EXAMPLE 

The three calls are to external routines named ROUT1A, routine2_, and rout3a_. Because rout3A is not in single quotation marks (character constant), a trailing underscore is added (Compaq Fortran adds a trailing underscore to external names on UNIX systems unless directed otherwise) and the letter A becomes a lowercase a. For details about adding underscores on Linux systems, see Section 11.4.2.

This feature can be useful when porting code in which different routine naming conventions are in use. By adding or removing the cDEC$ ALIAS directive, you can specify an alternate routine name without recoding the application.

The cDEC$ ALIAS and cDEC$ ATTRIBUTES ALIAS directives are synonymous.

11.2.2 The cDEC$ ATTRIBUTES Directive

Use the cDEC$ ATTRIBUTES directive to specify properties for data objects and procedures. These properties let you specify how data is passed and the rules for invoking procedures. The cDEC$ ATTRIBUTES directive is intended to simplify mixed-language calls with Compaq Fortran routines written in C or Assembler. The STDCALL keyword is synonymous with the C keyword on Compaq Tru64 UNIX and Linux systems.

The cDEC$ ATTRIBUTES directive takes the following form:


 cDEC$ ATTRIBUTES att [,att]... :: object [,object]... 

In this form:

c

Is the letter or character (c, C, *, !) that introduces the directive (see the Compaq Fortran Language Reference Manual).

att

Is one of the keywords listed in the Compaq Fortran Language Reference Manual. For example, C, ALIAS, REFERENCE, or VALUE.

object

Is the name of a data object used as an argument or procedure. Only one object is allowed when using the C, STDCALL, or ALIAS properties.

The Compaq Fortran Language Reference Manual) shows valid combinations of properties with the various types of objects.

The ATTRIBUTES options C, STDCALL, REFERENCE, VALUE, and VARYING all affect the calling convention of routines.

By default, Fortran passes all data by reference (except the hidden length argument of strings, which is a special case). If the C or STDCALL option is used, the default changes to passing almost all data by value except arrays.

In addition to the calling-convention options C and STDCALL, you can also specify argument options, VALUE and REFERENCE, to pass arguments by value or by reference, regardless of the calling convention option. Arrays can only be passed by reference.

Table 11-1 summarizes the effect of the most common Fortran calling-convention directives.

Table 11-1 Calling Conventions for ATTRIBUTES Options
Arguments Default C or STDCALL C or STDCALL with REFERENCE
Scalar Reference Value Reference
Scalar [value] Value Value Value
Scalar [reference] Reference Reference Reference
String Reference, Len: End String (1:1) Reference, Len: End
String [value] Error String(1:1) String(1:1)
String [reference] Reference, No Len Reference: No Len Reference: No Len
Array Reference Reference Reference
Array [value] Error Error Error
Array [reference] Reference Reference Reference
Derived type Reference Value, size dependent Reference
Derived type [value] Value, size dependent Value, size dependent Value, size dependent
Derived type [reference] Reference Reference Reference
F90 Pointer Descriptor Descriptor Descriptor
F90 Pointer [value] Error Error Error
F90 Pointer [reference] Descriptor Descriptor Descriptor

The terms used in Table 11-1 mean the following:
Term Description
[value] Assigned to the VALUE property
[reference] Assigned to the REFERENCE property
Value The argument value is pushed on the stack. All values are padded to the next 8-byte boundary.
Reference The 8-byte argument address is pushed on the stack.
Len: End The length of the string is pushed (by value) on the stack after all of the other arguments.
No Len The length of the string is not available to the called procedure.
String(1:1) For string arguments, the first character is converted to INTEGER(KIND=8) as in ICHAR(string(1:1)) and pushed onto the stack by value.
Error Produces a compiler error.
Descriptor 8-byte address of the array descriptor.
Size dependent Derived-type arguments specified by value are passed as follows:
  • Arguments of 1 to 4 bytes are passed by value
  • Arguments of 5 to 8 bytes are passed by value in two registers
  • Arguments of more than 8 bytes provide value semantics by passing a temporary storage address by reference.

The properties are described in the following sections.

11.2.2.1 C Property

The C property provides a convenient way for code written in Compaq Fortran to interact with routines written in C.

When applied to a subprogram, the C property defines the subprogram as having a specific set of calling conventions.

Table 11-2 summarizes the differences between the calling conventions:

Table 11-2 C Property and External Names
Item Fortran Default C Property Specified
Trailing underscore added to procedure names Yes No
Case of external subprogram names Lowercase, unless the ALIAS property is specified Lowercase, unless the ALIAS property is specified
Argument passing See Table 11-3 See Table 11-3

In addition to the case of external names and the trailing underscore, the C property affects how arguments are passed, as described in Table 11-3.

Table 11-3 C Property and Argument Passing
Argument Variable Type Fortran Default C Property Specified for Routine
Scalar (includes derived types) Passed by reference Passed by value
Scalar, with VALUE specified Passed by value Passed by value
Scalar, with REFERENCE specified Passed by reference Passed by reference
String Passed by reference with hidden length String (1:1) padded to integer length
String, with VALUE specified Error String (1:1) padded to integer length
String, with REFERENCE specified Passed by reference with no hidden length Passed by reference with no hidden length
Arrays, including pointers to arrays Always passed by reference or descriptor Always passed by reference or descriptor

If C is specified for a subprogram, arguments (except for arrays and characters) are passed by value. Subprograms using standard Fortran 95/90 conventions pass arguments by reference.

Character arguments are passed as follows:

When the C property is specified, the case of the external name (EXTERNAL statement) is forced to lowercase, even if -names as_is or -names uppercase was specified during compilation. To allow a mixed case or uppercase name when the C property is specified, specify the ALIAS property for the same subprogram or external name.

Example 11-1 shows the Compaq Fortran code that calls the C function pnst (no underscore) by using the cDEC$ ATTRIBUTES C directive and C language passing conventions.

Example 11-1 Calling C Functions and Passing Integer Arguments

! Using !DEC$ ATTRIBUTES to pass argument to C. File: pass_int_cdec.f90 
 
interface 
   subroutine pnst(i) 
     !DEC$ ATTRIBUTES C :: pnst 
     integer i 
   end subroutine 
end interface 
 
  integer :: i 
  i = 99 
  call pnst(i)             ! pass by value 
  print *,"99==",i 
end 

Example 11-2 shows the C function called pnst (no underscore) that is called by the example program shown in Example 11-1

Example 11-2 Calling C Functions and Passing Integer Arguments

/* get integer by value from Fortran. File: pass_int_cdec_c.c */ 
 
void pnst(int i) { 
    printf("99==%d\n",i); 
        i = 100; 
} 

The files (shown in Example 11-1 and Example 11-2) might be compiled, linked, and run as follows:


% cc -c  pass_int_cdec_c.c
% f90 -o pass_cdec pass_int_cdec.f90 pass_int_cdec_c.o
% pass_cdec 
99==99 
99==          99

11.2.2.2 ALIAS Property

You can specify the ALIAS property as cDEC$ ALIAS or as cDEC$ ATTRIBUTES ALIAS; both are equivalent. The ALIAS property allows you to specify that the external name of an external subprogram is different from the name by which the calling procedure references it (see Section 11.2.1).

When both ALIAS and C properties are used for a subprogram or external (EXTERNAL statement) name, the ALIAS property takes precedence over the C property. This allows you to specify case-sensitive names (the C attribute sets them to lowercase).

11.2.2.3 REFERENCE and VALUE Properties

The following cDEC$ ATTRIBUTES properties specify how a dummy argument is to be passed:

When a complex (KIND=4 or KIND=8) argument is passed by value, two floating-point arguments (one containing the real part, the other containing the imaginary part) are passed by immediate value. Conversely, if a COMPLEX parameter to a routine is specified as received by value (or given the C attribute), two REAL parameters are received and stored in the real and imaginary parts of the COMPLEX parameter specified.

Character values, substrings, assumed-size arrays, and adjustable arrays cannot be passed by value; neither can REAL*16 and COMPLEX*32 data. When REFERENCE is specified for a character argument, the string is passed with no length.

VALUE is the default if the C property is specified in the subprogram definition.

Consider the following free-form example, which passes an integer by value:


  interface 
    subroutine foo (a) 
     !DEC$ ATTRIBUTES C :: foo 
        integer a 
    end subroutine foo 
  end interface    

This subroutine can be invoked from Compaq Fortran using the name foo (no underscore):


   integer i 
   i = 1 
   call foo(i) 
 
   end program 

This is the actual subroutine code:


    subroutine foo (i) 
     !DEC$ ATTRIBUTES C :: foo 
        integer i 
        i = i + 1 
        . 
        . 
    end subroutine foo 

For More Information:

11.2.2.4 EXTERN and VARYING Properties

The EXTERN property specifies that a variable is allocated in another source file. EXTERN can be used in global variable declarations, but it must not be applied to dummy arguments.

You must use EXTERN when accessing variables declared in other languages.

The VARYING directive allows a variable number of calling arguments. If VARYING is specified, the C property must also be specified.

When using the VARYING directive, either the first argument must be a number indicating how many arguments to process, or the last argument must be a special marker (such as -1 ) indicating it is the final argument. The sequence of the arguments, and types and kinds, must be compatible with the called procedure.

For More Information:

See the Compaq Fortran Language Reference Manual

11.3 Calling Between Compaq Fortran 77 and Compaq Fortran

On Compaq Tru64 UNIX systems, you can call a Compaq Fortran 77 subprogram from Compaq Fortran or call a Compaq Fortran subprogram from Compaq Fortran 77 (with a few exceptions). A Compaq Fortran 77 procedure and a Compaq Fortran procedure can also perform I/O to the same unit number.

11.3.1 Argument Passing and Function Return Values

The recommended rules for passing arguments and function return values between Compaq Fortran 77 and Compaq Fortran procedures are as follows:

Example 11-3 and Example 11-4 show passing an array from a Compaq Fortran program to a Compaq Fortran 77 subroutine that prints its value.

Example 11-3 shows the Compaq Fortran program (file array_to_f77.f90 ). It passes the same argument as a target and a pointer. In both cases, it is received by reference by the Compaq Fortran 77 subroutine as a target (regular) argument. The interface block in Example 11-3 is not needed, but does allow data type checking.

Example 11-3 Compaq Fortran Program Calling a Compaq Fortran 77 Subroutine

 ! Pass arrays to f77 routine. File: array_to_f77.f90 
 
 ! this interface block is not required, but must agree 
 ! with actual procedure. It can be used for type checking. 
 
 interface                    ! Procedure interface block 
   subroutine meg(a) 
   integer :: a(3) 
   end subroutine 
 end interface 
 
 integer, target :: x(3) 
 integer, pointer :: xp(:) 
 
 x = (/ 1,2,3 /) 
 xp => x                         
 
 call meg(x)                  ! Call f77 subroutine twice. 
 call meg(xp)                
 end 

Example 11-4 shows the Compaq Fortran 77 subprogram called by the Compaq Fortran program (file array_f77.f ).

Example 11-4 Compaq Fortran 77 Subroutine Called by a Compaq Fortran Program

      ! Get array argument from F90. File: array_f77.f 
 
       subroutine meg(a) 
       integer a(3) 
       print *,a 
       end 

These files (shown in Example 11-3 and Example 11-4) might be compiled, linked, and run as follows:


% f77 -c array_f77.f
% f90 -o array_to_f77 array_to_f77.f90 array_f77.o
% array_to_f77
           1           2           3 
           1           2           3 

In Example 11-3, because array a is not defined as a pointer in the interface block, the Compaq Fortran pointer variable xp is passed as target data by reference (address of the target data).

However, if the interface to the dummy argument had the POINTER attribute, the variable xp would be passed by descriptor. This descriptor would not work with the Compaq Fortran 77 program shown in Example 11-4.

For More Information:


Previous Next Contents Index