Compaq Fortran
User Manual for
Tru64 UNIX
and Linux Alpha Systems
10.4.5 f90 Command -convert keyword Option Method
You can specify only one numeric format for all unit numbers
by using the
f90
command option method, unless you also use the environment variable
method or CONVERT specifier method. You specify the numeric format at
compile time and must compile all routines under the same
-convert keyword
option (the
keyword
must be in lowercase) or the equivalent OPTIONS statement. You can use
one source program and compile it using different
f90
commands to create multiple executable programs that each read a
certain format.
The other methods take precedence over this method. For instance, you
might use the environment variables or OPEN CONVERT specifier method to
specify each unit number that will use a format other than that
specified using the
f90
command option method.
For example, the following shell commands compile program
file.f90
to use VAX D_float and F_float data. Data is converted between the file
format and the little endian memory format (little endian integers and
S_float, T_float, and X_float little endian IEEE floating-point
format). The created file,
vaxd_convert.out
, is then run:
% f90 -convert vaxd -o vaxd_convert.out file.f90
% vaxd_convert.out
|
Because this method affects all unit numbers, you cannot read
or write data in different formats if you only use the
f90 -convert keyword
method. To specify a different format for a particular unit
number, use the
f90 -convert keyword
method in combination with an environment variable method or the OPEN
statement CONVERT specifier method.
10.4.6 Additional Notes on Nonnative Data
The following notes apply to porting nonnative data:
- When porting source code along with the unformatted data, vendors
might use different units for specifying the record length (RECL
specifier, see Section 7.4.4) of unformatted files. While formatted
files are specified in units of characters (bytes), unformatted files
are specified in longword units for Compaq Fortran and some other
vendors. The Fortran 90 standard, in Section 9.3.4.5, states: "If
the file is being connected for unformatted input/output, the length is
measured in processor-dependent units."1
- Certain vendors apply different OPEN statement defaults to
determine the record type. The default record type (RECORDTYPE) with
Compaq Fortran depends on the values for the ACCESS and FORM specifiers
for the OPEN statement, as described in the Compaq Fortran Language Reference Manual.
-
Certain vendors use a different identifier for the logical data types,
such as hex FF instead of 01 to denote "true."
- Source code being ported might be coded specifically for big
endian use.
For More Information:
- On OPEN statement specifiers, see the Compaq Fortran Language Reference Manual.
- On Compaq Fortran file characteristics, see the Section 7.4.
- On Compaq Fortran record types, see Section 7.4.3 and
Section 7.8.
Note
1 American National Standard Fortran
90, ANSI X3.198-1991, and International Standards Organization standard
ISO/IEC 1539:1991
|
Chapter 11
Procedure Data Interfaces and Mixed Language Programming
This chapter provides information on the following topics:
- Passing data arguments and function return values by using
Compaq Fortran procedures and subprograms ( Section 11.1)
- Using the cDEC$ ALIAS and cDEC$ ATTRIBUTES directives
( Section 11.2) to:
- Specify an alternate name (alias) for external subprograms
- Change the way certain arguments are passed
- Request that C language rules be used for external names and
arguments being passed
- Passing data arguments and function return values between Compaq
Fortran and Compaq Fortran 77 procedures and subprograms
( Section 11.3)
- Passing data arguments and function return values between
Compaq Fortran and C functions on Compaq Tru64 UNIX and Linux systems
( Section 11.4)
11.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.
11.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 a Compaq Fortran array descriptor. An array descriptor
is generated when an appropriate explicit interface is used for certain
types of array arguments.
- In parallel HPF programs executed with the Compaq Parallel Software
Environment, an explicit interface is needed in order to avoid
remapping of distributed data at the procedure interface. For more
information, see the Compaq Parallel Software Environment documentation.
For More Information:
On Compaq Fortran array descriptors, see Section 11.1.7.
11.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 11.1.3).
For subprograms with no explicit interface, declare the subprogram
name as external. You can do this by 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.
11.1.3 Using Procedure Interface Blocks
Procedure interface blocks allow you to specify an explicit interface
for a subprogram as well as 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.
In parallel HPF programs (TU*X ONLY), any DISTRIBUTE, ALIGN, and INHERIT
(!HPF) directives for the dummy arguments must also be included. For
more information about procedure interface blocks for parallel HPF
programs, see the Compaq Parallel Software Environment documentation.
- 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.
11.1.4 Passing Arguments and Function Return Values
Compaq Fortran on Tru64 UNIX and Linux systems uses the same
argument-passing conventions as Compaq Fortran 77 on Compaq Tru64 UNIX
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. The address
of the argument is passed.
Unless explicitly specified otherwise
(such as with the cDEC$ ATTRIBUTES directive or the %VAL built-in
function), an argument contains the address of the data being passed,
not the data itself.
Assumed-shape arrays and deferred-shape arrays
are passed by array descriptor.
Arguments omitted by adding an extra comma (,) are passed as a zero by
immediate value. OPTIONAL arguments that are not passed are also
handled this way.
- 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 as arguments by reference along with an extra argument, called a
"hidden length" argument, that gets passed by value after all
actual arguments.
The hidden length is an integer value. If two
character scalar variables are passed, the argument list contains two
extra hidden length arguments that respectively contain the length of
the passed character arguments. Dummy arguments for character data can
use an assumed length. You can use the
-mixed_str_len_arg
option to place the hidden length directly after its corresponding
character argument instead of sequentially at the end of the argument
list. See Section 3.54.
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 or the null character escape sequence (described in
the Compaq Fortran Language Reference Manual).
- External names have a trailing underscore (_) appended to their
name and are in lowercase. On Linux systems, if an external name has an
underscore in it, then two underscores are appended. For example,
EXTERNAL foo_bar
becomes
EXTERNAL foo_bar__
.
The Compaq Fortran compiler appends the underscore to any
reference to an external procedure name, as well as Compaq Fortran
procedure declarations in the object file. This is mostly a concern
when the program uses routines in Compaq Fortran and C, as described in
Section 11.4.2.
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 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 Section 11.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 (as 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.
You can pass an actual array to a dummy array of the same rank or you
can pass an array section. If you use an assumed-shape array, the
extents of the dummy array argument are taken from the actual array
argument.
Other rules which apply to passing arrays and pointers
are described in Section 11.1.5, Section 11.1.6, and 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 11-3 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 arguments.
For More Information:
- On passing arguments, function return values, and the contents of
registers on Compaq Tru64 UNIX systems, see the Compaq Tru64 UNIX Calling Standard for Alpha Systems.
- On intrinsic data types, see Chapter 9 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.
11.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. Using array element sequence associations
is discussed in the Compaq Fortran Language Reference Manual.
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 11.1.7.
11.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.
- Dummy arguments have the TARGET attribute.
- Both actual and dummy arguments have neither attribute.
You can specify an actual argument of type POINTER and a dummy argument
of type POINTER. You must use an explicit interface that defines the
dummy argument with the POINTER attribute in the code containing the
actual argument. This ensures that the pointer is passed, rather than
the array data itself.
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.
11.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)
- Allocatable arrays
- 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, a descriptor is not used.
However, for cases where the called routine needs the information in
the Compaq Fortran descriptor, declare the routine with an
assumed-shape or pointer argument and an explicit interface.
The byte components of the Compaq Fortran descriptor follow:
- Byte 0 contains a count of the number of dimensions (rank).
- Byte 1 should always contain a 1.
- Byte 2 contains the data type of the result, as follows:
- 1 for INTEGER (KIND=1)
- 2 for INTEGER (KIND=2)
- 3 for INTEGER (KIND=4)
- 4 for INTEGER (KIND=8)
- 5 for LOGICAL (KIND=1)
- 6 for LOGICAL (KIND=2)
- 7 for LOGICAL (KIND=4)
- 8 for LOGICAL (KIND=8)
- 9 for REAL (KIND=4)
- 10 for REAL (KIND=8)
- 11 for REAL (KIND=16)
- 12 for COMPLEX (KIND=4) or COMPLEX*8
- 13 for COMPLEX (KIND=8) or COMPLEX*16
- 14 for CHARACTER
- 15 for RECORD
- 17 for COMPLEX (KIND=16) or COMPLEX*32
- Bytes 3 to 7 (inclusive) are reserved.
- Bytes 8 to 15 contain the element length for character data, in
bytes.
- Bytes 16 to 23 contain the address of the first element of an array.
- Bytes 24 to 39 are reserved.
- The remaining bytes (40 to 207) contain information about each
array dimension, as follows:
- Bytes 40 to 63 contain dimension information for rank 1
- Bytes 64 to 87 contain dimension information for rank 2
- Bytes 88 to 111 contain dimension information for rank 3
- Bytes 112 to 135 contain dimension information for rank 4
- Bytes 136 to 159 contain dimension information for rank 5
- Bytes 160 to 183 contain dimension information for rank 6
- Bytes 184 to 207 contain dimension information for rank 7
Within the dimension information (24 bytes) for each rank:
- Bytes 0 to 7 contain the number of bytes between two successive
elements in this dimension.
- Bytes 8 to 15 contain the upper bound.
- Bytes 16 to 23 contain the lower bound.
For example, consider the following 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 would contain the following values:
- Byte 0 contains 2 (number of dimensions).
- Byte 1 contains 1 (always).
- Byte 2 contains 3 (data type of the result is the default INTEGER
size, usually INTEGER (KIND=4)).
- Bytes 3 to 15 are reserved.
- Bytes 16 to 23 contain the address of the first element.
- Bytes 24 to 39 are reserved.
- Bytes 40 to 63 contain dimension information for rank 1, as follows:
- Bytes 40 to 47 contain --8 (distance between elements)
- Bytes 48 to 55 contain 5 (upper bound)
- Bytes 56 to 63 contain 1 (lower bound)
- Bytes 64 to 87 contain dimension information for rank 2, as follows:
- Bytes 64 to 71 contain 120 (distance between elements)
- Bytes 72 to 80 contain 3 (upper bound)
- Bytes 81 to 87 contain 1 (lower bound)
- Byte 87 is the last byte.