Compaq Fortran
User Manual for
OpenVMS Alpha
Systems
Chapter 10
Using Compaq Fortran in the Common Language Environment
This chapter provides information on the following topics:
- Passing data arguments and function return values by using
Compaq Fortran procedures and subprograms ( Section 10.1)
- Compaq Fortran argument-passing mechanisms ( Section 10.2)
- Using the cDEC$ ALIAS and cDEC$ ATTRIBUTES directives to specify an
alternate name (alias) for external subprograms and change the way
certain arguments are passed ( Section 10.3)
- The common language environment provided by the OpenVMS procedure
calling standard ( Section 10.4)
- Understanding OpenVMS system routines ( Section 10.5)
- General considerations about calling routines ( Section 10.6)
- Calling OpenVMS system services ( Section 10.7)
- Passing data arguments and function return values between Compaq
Fortran and Compaq Fortran 77 procedures and subprograms
( Section 10.8)
- Passing data arguments and function return values between
Compaq Fortran and C functions on OpenVMS Alpha systems ( Section 10.9)
Compaq Fortran provides you with a variety of mechanisms for gaining
access to procedures and system services external to your
Compaq Fortran programs. By including CALL statements or function
references in your source program, you can use procedures such as
mathematical functions, OpenVMS system services, and routines written
in such languages as Compaq Fortran 77 and Compaq C.
The Compaq Fortran compiler operates within the OpenVMS common language
environment, which defines certain calling procedures and guidelines.
These guidelines allow you to use Compaq Fortran to call OpenVMS system
or library routines and routines written in different languages
(usually called mixed-language programming).
This chapter provides information on the OpenVMS procedure-calling
standard and how to access OpenVMS system services.
For More Information:
About calling and using the RMS (Record Management Services) system
services, see Chapter 11.
10.1 Compaq Fortran Procedures and Argument Passing
The bounds of the main program are usually defined by using PROGRAM and
END or END PROGRAM statements. Within the main program, you can define
entities related to calling a function or subroutine, including modules
and interface blocks.
A function or subroutine is considered a subprogram.
A subprogram can accept one or more data values passed from the calling
routine; the values are called arguments.
There are two types of arguments:
- Actual arguments are specified in the subprogram
call.
- Dummy arguments are variables within the function
or subroutine that receive the values (from the actual arguments).
The following methods define the interface between procedures:
- Declare and name a function with a FUNCTION statement and terminate
the function definition with an END FUNCTION statement. Set the value
of the data to be returned to the calling routine by using the function
name as a variable in an assignment statement (or by specifying RESULT
in a FUNCTION statement).
Reference a function by using its name in
an expression.
- Declare and name a subroutine with a SUBROUTINE statement and
terminate the subroutine definition with an END SUBROUTINE statement.
No value is returned by a subroutine.
Reference a subroutine by using its name in a CALL statement (or
use a defined assignment statement).
- For an external subprogram, depending on the type
of arguments or function return values, you may need to declare an
explicit interface to the arguments and function return value by using
an interface block.
Declare and name an interface block with an INTERFACE statement and
terminate the interface block definition with an END INTERFACE
statement. The interface body that appears between
these two statements consists of function or subroutine specification
statements.
- You can make data, specifications, definitions,
procedure interfaces, or procedures globally available to the
appropriate parts of your program by using a module
(use association).
Declare a module with a MODULE statement and terminate the module
definition with an END MODULE statement. Include the definitions and
other information contained within the module in appropriate parts of
your program with a USE statement. A module can contain interface
blocks, function and subroutine declarations, data declarations, and
other information.
For More Information:
On the Compaq Fortran language, including statement functions and
defined assignment statements not described in this manual, see the
Compaq Fortran Language Reference Manual.
10.1.1 Explicit and Implicit Interfaces
An explicit interface occurs when the properties of
the subprogram interface are known within the scope of the
function or subroutine reference.
For example, the function reference or CALL statement occurs at a point
where the function or subroutine definition is known through host or
use association. Intrinsic procedures also have an explicit interface.
An implicit interface occurs when the properties of
the subprogram interface are not known within the scope of the
function or subroutine reference. In this case, the procedure data
interface is unknown to the compiler. For example, external routines
(EXTERNAL statement) that have not been defined in an interface block
have an implicit interface.
In most cases, you can use a procedure interface block to make an
implicit interface an explicit one. An explicit interface provides the
following advantages over an implicit interface:
- Better compile-time argument checking and fewer run-time errors
- In some cases, faster run-time performance
- Ease of locating problems in source files since the features help
to make the interface self-documenting
- Allows use of some language features that require an explicit
interface, such as array function return values.
- When passing certain types of arguments between Compaq Fortran and
non-Fortran languages, an explicit interface may be needed. For
example, detailed information about an assumed-shape array argument can
be obtained from the passed array descriptor. The array descriptor is
generated when an appropriate explicit interface is used for certain
types of array arguments.
For More Information:
On Compaq Fortran array descriptors, see Section 10.1.7.
10.1.2 Types of Compaq Fortran Subprograms
There are three major types of subprograms:
- A subprogram might be local to a single program unit (known only
within its host). Since the subprogram definition and all its
references are contained within the same program unit, it is called an
internal subprogram.
An internal subprogram has an explicit interface.
- A subprogram needed in multiple program units should be placed
within a module. To create a module subprogram within
a module, add a CONTAINS statement followed by the subprogram code. A
module subprogram can also contain internal subprograms.
A module
subprogram has an explicit interface in those program units that
reference the module with a USE statement (unless it is declared
PRIVATE).
- External subprograms are needed in multiple
program units but cannot be placed in a module. This makes their
procedure interface unknown in the program unit in which the reference
occurs. Examples of external subprograms include general-purpose
library routines in standard libraries and subprograms written in other
languages, like C or Ada.
Unless an external subprogram has an associated interface block, it has
an implicit interface. To provide an explicit interface for an external
subprogram, create a procedure interface block (see Section 10.1.3).
For subprograms with no explicit interface, declare the subprogram
name as external using the EXTERNAL statement within the program unit
where the external subprogram reference occurs. This allows the linker
to resolve the reference.
An external subprogram must not contain
PUBLIC or PRIVATE statements.
10.1.3 Using Procedure Interface Blocks
Procedure interface blocks allow you to specify an explicit interface
for a subprogram as well as to define generic procedure names. This
section limits discussion to those interface blocks used to provide an
explicit subprogram interface. For complete information on interface
blocks, see the Compaq Fortran Language Reference Manual.
The components of a procedure interface block follow:
- Begin a procedure interface block with an INTERFACE statement.
Unless you are defining a generic procedure name, user-defined
operator, or user-defined assignment, only the word INTERFACE is needed.
- To provide the interface body, copy the procedure specification
statements from the actual subprogram, including:
- The FUNCTION or SUBROUTINE statements.
- The interface body. For a procedure interface block, this includes
specification (declaration) statements for the dummy arguments and a
function return value (omit data assignment, FORMAT, ENTRY, DATA, and
related statements).
The interface body can include USE statements
to obtain definitions.
- The END FUNCTION or END SUBROUTINE statements.
- Terminate the interface block with an END INTERFACE statement.
- To make the procedure interface block available to multiple program
units, you can do one of the following:
- Place the procedure interface block in a module. Reference the
module with a USE statement in each program unit that references the
subprogram (use association).
- Place the procedure interface block in each program unit that
references the subprogram.
For an example of a module that contains a procedure interface block,
see Section 1.3.
10.1.4 Passing Arguments and Function Return Values
Compaq Fortran uses the same argument-passing conventions as Compaq
Fortran 77 on OpenVMS Alpha systems for non-pointer scalar variables
and explicit-shape and assumed-size arrays.
When calling Compaq Fortran subprograms, be aware that Compaq Fortran
expects to receive arguments the same way it passes them.
The main points about argument passing and function return values are
as follows:
- Arguments are generally passed by reference (arguments contain an
address).
An argument contains the address of the data
being passed, not the data itself (unless explicitly specified
otherwise, such as with the cDEC$ ATTRIBUTES directive or the %VAL
built-in function).
Assumed-shape arrays and deferred-shape arrays are passed by array
descriptor.
Character data is passed by character descriptor.1
Arguments omitted by adding an extra comma (,) are passed as a zero by
immediate value (see Section 10.7.4). Such arguments include OPTIONAL
arguments that are not passed.
Any argument specified using the
%DESCR built-in function is also passed by descriptor (see
Section 10.2).
- Function return data is usually passed by immediate value (function
return contains a value). Certain types of data (such as array-valued
functions) are passed by other means.
The value being returned from
a function call usually contains the actual data, not the
address of the data.
- Character variables, explicit-shape character arrays, and
assumed-size character arrays
are passed by a character descriptor (except for character constant
actual arguments when /BY_REF_CALL is used).
Dummy arguments for
character data can use an assumed length.
When passing character arguments to a C routine as strings, the
character argument is not automatically null-terminated by the
compiler. To null-terminate a string from Compaq Fortran, use the CHAR
intrinsic function (described in the Compaq Fortran Language Reference Manual).
The arguments passed from a calling routine must match the dummy
arguments declared in the called function or subroutine (or other
procedure), as follows:
- Arguments must be in the same order, unless argument keywords are
used.
Arguments are kept in the same position as they are specified
by the user. The exception to same position placement is the use of
argument keywords to associate dummy and actual arguments.
- Each corresponding argument or function return value must at least
match in data type, kind, and rank, as follows:
- The primary Compaq Fortran intrinsic data types are character,
integer, logical, real, and complex.
To convert data from one data
type to another, use the appropriate intrinsic procedures described in
the Compaq Fortran Language Reference Manual.
Also, certain attributes of a data item may
have to match. For example, if a dummy argument has the POINTER
attribute, its corresponding actual argument must also have the POINTER
attribute (see Section 10.1.6).
- You can use the kind parameter to specify the length of each numeric
intrinsic type, such as INTEGER (KIND=8). For character lengths, use
the LEN specifier, perhaps with an assumed length for dummy character
arguments (LEN=*).
- The rank (number of dimensions) of the actual
argument is usually the same (or less than) the rank of the dummy
argument, unless an assumed-size dummy array is used.
When using an explicit interface, the rank of the actual argument must
be the same as the rank of the dummy argument.
For example, when
passing a scalar actual argument to a scalar dummy argument (no more
than one array element or a nonarray variable), the rank of both is 0.
Other rules which apply to passing arrays and pointers are
described in Section 10.1.5, Section 10.1.6, and in the Compaq Fortran Language Reference Manual.
- The means by which the argument is passed and received (passing
mechanism) must match.
By default, Compaq Fortran arguments are
passed by reference. (See Table 10-1 for information about passing
arguments with the C property.)
When calling functions or other
routines that are intended to be called from another language (such as
C), be aware that these languages may require data to be passed by
other means, such as by value.
Most Compaq Fortran function return
values are passed by value. Certain types of data (such as array-valued
functions) are passed by other means.
In most cases, you can change
the passing mechanism of actual arguments by using the following Compaq
extensions:
- To explicitly specify the procedure (argument or function return)
interface, provide an explicit interface.
You can use interface
blocks and modules to specify INTENT and other attributes of actual or
dummy arguments.
For More Information:
- On passing arguments, function return values, and the contents of
registers on OpenVMS Alpha systems, see the OpenVMS Calling Standard.
- On intrinsic data types, see Chapter 8 and the Compaq Fortran Language Reference Manual.
- On intrinsic procedures and attributes available for array use, see
the Compaq Fortran Language Reference Manual.
- On explicit interfaces and when they are required, see the
Compaq Fortran Language Reference Manual.
- On a Compaq Fortran example program that uses an external
subprogram and a module that contains a procedure interface block, see
Example 1-3.
10.1.5 Passing Arrays as Arguments
Certain arguments or function return values require the use of an
explicit interface, including assumed-shape dummy arguments, pointer
dummy arguments, and function return values that are arrays. This is
discussed in the Compaq Fortran Language Reference Manual.
When passing arrays as arguments, the rank and the extents (number of
elements in a dimension) should agree, so the arrays have the same
shape and are conformable. If you use an assumed-shape
array, the rank is specified and extents of the dummy array argument
are taken from the actual array argument.
If the rank and extent (shape) do not agree, the arrays are
not conformable.
The assignment of elements from the actual array to the noncomformable
(assumed-size or explicit-shape) dummy array is done by using array
element sequence association.
Certain combinations of actual and dummy array arguments are disallowed.
For More Information:
- On the types of arrays and passing array arguments, see the
Compaq Fortran Language Reference Manual.
- On explicit interfaces and when they are required, see the
Compaq Fortran Language Reference Manual.
- On array descriptors, see Section 10.1.7
10.1.6 Passing Pointers as Arguments
Previous sections have discussed the case where the actual and dummy
arguments have neither the POINTER attribute nor the TARGET attribute.
The argument passing rules of like type, kind, and rank (for
conformable arrays) or array element sequence association (for
noncomformable arrays) apply when:
- Both actual and dummy arguments have the POINTER attribute (and
must be conformable)
- Dummy arguments have the TARGET attribute
- Both actual and dummy arguments have neither attribute
If you specify an actual argument of type POINTER and a dummy argument
of type POINTER, the dummy argument receives the correct pointer value
if you specify (in the code containing the actual argument) an
appropriate explicit interface that defines the dummy argument with the
POINTER attribute and follows certain rules.
However, if you specify an actual argument of type POINTER and do
not specify an appropriate explicit interface (such as an
interface block), it is passed as actual (target) data.
For More Information:
On using pointers and pointer arguments, see the Compaq Fortran Language Reference Manual.
10.1.7 Compaq Fortran Array Descriptor Format
When using an explicit interface (by association or procedure interface
block), Compaq Fortran will generate a descriptor for the following
types of dummy argument data structures:
- Pointers to arrays (array pointers)
- Assumed-shape arrays
To allow calling between Compaq Fortran 77 and Compaq Fortran, certain
data structure arguments also supported by Compaq Fortran 77 do not use
a descriptor, even when an appropriate explicit interface is provided.
For example, since explicit-shape and assumed-size arrays are supported
by both Compaq Fortran 77 and Compaq Fortran, an array descriptor is
not used.
When calling between Compaq Fortran and a non-Fortran language (such as
C), you can specify an appropriate explicit interface or use an
implicit interface.
However, for cases where the called routine needs the information in
the array descriptor, declare the routine with an assumed-shape
argument and an explicit interface.
The array descriptor used by Compaq Fortran is the OpenVMS
Noncontiguous Array Descriptor as described in the OpenVMS Calling Standard. In
the DSC$B_AFLAGS byte, bit DSC$V_FL_UNALLOC specifies whether storage
has or has not been set for this array. If this bit is set, the array
has not yet been allocated.
For example, for 32-bit address access, consider the following array
declaration:
INTEGER,TARGET :: A(10,10)
INTEGER,POINTER :: P(:,:)
P => A(9:1:-2,1:9:3)
CALL F(P)
.
.
.
|
The descriptor for actual argument P (using 32-bit addresses) would
contain the following values:
- length (DSC$W_LENGTH) contains 4.
- dtype (DSC$B_DTYPE) contains DSC$K_DTYPE_L.
- class (DSC$B_CLASS) contains DSC$K_CLASS_NCA.
- pointer (DSC$A_POINTER) contains the address of A (9,1).
- scale (DSC$B_SCALE) contains 0.
- digits (DSC$B_DIGITS) contains 0.
- aflags (DSC$B_AFLAGS) contains 0, since A is allocated, the
V_FL_UNALLOC bit is clear.
- dimen (DSC$B_DIMEN) contains 2.
- arsize (DSC$L_ARSIZE) contains 60.
- DSC$A_A0 contains the address of A(0,0).
- DSC$L_Si contains the stride of dimension i.
- DSC$L_Li contains the lower bound of dimension i.
- DSC$L_Ui contains the upper bound of dimension i.
For information about the Noncontiguous Array Descriptor when 64-bit
addressing is requested (cDEC$ ATTRIBUTES ADDRESS64 directive), see the
OpenVMS Calling Standard.
Note
1 For compatibility with older Compaq
Fortran 77 OpenVMS VAX programs, character constant actual arguments
(string literals) can be passed by reference if the Compaq Fortran
program was compiled with the /BY_REF_CALL qualifier (see
Section 2.3.8).
|
10.2 Argument-Passing Mechanisms and Built-In Functions
The OpenVMS procedure-calling standard defines three mechanisms by
which arguments are passed to procedures:
- By immediate value---The argument list entry contains the value.
- By reference---The argument list entry contains the address of the
value.
- By descriptor---The argument list entry contains the address of a
descriptor of the value.
By default, Compaq Fortran uses the reference and descriptor mechanisms
to pass arguments, depending on each argument's data type:
- The reference mechanism is used to pass all actual arguments that
are numeric: logical, integer, real, and complex.
- The descriptor mechanism is used to pass all actual arguments that
are character, Fortran 90 pointers, assumed-shape arrays, and
deferred-shape arrays (except for character constant actual arguments
when the Compaq Fortran program was compiled with /BY_REF_CALL).
When a Compaq Fortran program needs to call a routine written in a
different language (or in some cases a Fortran 90 subprogram), there
may be a need to use a form other the Compaq Fortran default
mechanisms. For example, OpenVMS system services may require that
certain numeric arguments be passed by immediate value instead of by
reference.
For cases where you cannot use the default passing mechanisms,
Compaq Fortran provides three built-in functions for passing arguments.
It also provides a built-in function for computing addresses for use in
argument lists. These built-in functions are as follows:
- %VAL, %REF, %DESCR---argument list built-in functions
- %LOC---general usage built-in function
Except for the %LOC built-in function, which can be used in any
arithmetic expression, these functions can appear only as
unparenthesized arguments in argument lists. The three argument list
built-in functions and %LOC built-in function are rarely used to call a
procedure written in Compaq Fortran.
The use of these functions in system service calls is described in
Section 10.7.4. The sections that follow describe their use in general.
Instead of using the Compaq Fortran built-in functions, you can use the
cDEC$ ATTRIBUTES directive to change the Compaq Fortran default passing
mechanisms (see Section 10.3.2).
10.2.1 Passing Arguments by Descriptor---%DESCR Function
The %DESCR function passes its argument by descriptor. It has the
following form:
The argument generated by the compiler is the address of a descriptor
of the argument (arg). The argument value can be any Fortran 90
expression. The argument value must not be a derived type,
record name, record array name, or record array element. The compiler
can generate OpenVMS descriptors for all Fortran data types.
In Compaq Fortran, the descriptor mechanism is the default for passing
character arguments, Fortran 90 pointers, assumed-shape arrays, and
deferred-shape arrays. This is because the subprogram may need to know
the length or other information about the character, pointer, or array
argument. Compaq Fortran always generates code to refer to character
dummy arguments through the addresses in their character descriptors.
For More Information:
On Compaq Fortran array descriptors, see Section 10.1.7.
10.2.2 Passing Addresses---%LOC Function
The %LOC built-in function computes the address of a storage element as
an INTEGER (KIND=8) (64-bit) value. With 64-bit addressing (cDEC$
ATTRIBUTE ADDRESS64 directive specified), all 64-bits are used. With
32-bit addressing (cDEC$ ATTRIBUTE ADDRESS64 directive omitted), only
the lower 32 bits are used. You can then use this value in an
arithmetic expression. It has the following form:
The %LOC function is particularly useful for certain system services or
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:
- On declaring volatile data structures, see the Compaq Fortran Language Reference Manual.
- On optimization and declaring volatile data, see Section 5.7.3.
- On an example that uses the %LOC function, see Example 10-4.
10.2.3 Passing Arguments by Immediate Value---%VAL Function
The %VAL function passes the argument list entry as a 64-bit immediate
value. It has the following form:
The argument-list entry generated by the compiler is the value of the
argument (arg). The argument value can be a constant, variable, array
element, or expression of type INTEGER, LOGICAL, REAL (KIND=4), REAL
(KIND=8), COMPLEX (KIND=4), or COMPLEX (KIND=8).
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.
If the value is a byte, word, or longword, it is sign-extended to a
quadword (eight bytes).
To produce a zero-extended value rather than a sign-extended value, use
the ZEXT intrinsic function.
For More Information:
- On intrinsic procedures, see the Compaq Fortran Language Reference Manual.
- On an example of passing integer data by value (using %VAL) and by
reference (default) to a C function, see Section 10.9.7.
- On the ZEXT intrinsic function, see Compaq Fortran Language Reference Manual.
- On the %VAL built-in function, see the Compaq Fortran Language Reference Manual.