Previous | Contents | Index |
The %REF function passes the argument by reference. It has the following form:
%REF(arg) |
The argument-list entry generated by the compiler 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.
10.2.5 Examples of Argument Passing Built-in Functions
The following examples demonstrate the use of the argument list built-in functions.
CALL SUB(2,%VAL(2)) |
CHARACTER(LEN=10) A,B CALL SUB(A,%REF(B)) |
INTEGER IARY(20), JARY(20) CALL SUB(IARY,%DESCR(JARY)) |
This section provides reference information about the following directives:
Compaq Fortran now 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 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. The default for the Compaq Fortran compiler is to force the name into uppercase.
If external-name is a symbolic name, the symbolic name (in uppercase) is used as the external name for the specified internal name. Any other declaration of the specified symbolic name is ignored for the purposes of the ALIAS directive.
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. Use single quotation marks (character constant) to specify a case-sensitive name.
This feature can be useful when porting code to systems where 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.
10.3.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 cDEC$ ATTRIBUTES directive takes the following form:
cDEC$ ATTRIBUTES att [,att]... :: object [,object]... |
In this form:
The Compaq Fortran Language Reference Manual explains the valid combinations of properties with the various types of objects.
The ATTRIBUTES properties are described in the following sections:
The C property provides a convenient way for 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.
The C property affects how arguments are passed, as described in Table 10-1.
Argument Variable Type | Fortran Default | C Property Specified for Routine |
---|---|---|
Scalar (includes derived types) | Passed by reference | Passed by value (large derived type variables may be passed by reference) |
Scalar, with VALUE specified | Passed by value | Passed by value |
Scalar, with REFERENCE specified | Passed by reference | Passed by reference |
String | Passed by character descriptor | Passes the first character of the string, padded to a full integer |
String, with VALUE specified | Error | Passes the first character of the string, padded to a full integer |
String, with REFERENCE specified | Passed by reference | Passed by reference |
Arrays, including pointers to arrays | Always passed by reference | Always passed by reference |
If C is specified for a subprogram, arguments (except for arrays and characters) are passed by value. Subprograms using standard Fortran conventions pass arguments by reference.
Character arguments are passed as follows:
Example 10-1 shows Compaq Fortran code that calls the C function pnst by using the cDEC$ ATTRIBUTES C directive and C language passing conventions.
Example 10-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 10-2 shows the C function called pnst that is called by the example program shown in Example 10-1
Example 10-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 10-1 and Example 10-2) might be compiled, linked, and run as follows:
$ CC PASS_INT_CDEC_C.C $ FORTRAN PASS_INT_CDEC.F90 $ LINK/EXECUTABLE=PASS_CDEC PASS_INT_CDEC, PASS_INT_CDEC_C $ RUN PASS_CDEC 99==99 99== 99 |
You can specify the ALIAS property as cDEC$ ALIAS or as cDEC$ ATTRIBUTES ALIAS; they are equivalent, except that using cDEC$ ALIAS allows symbol names (see Section 10.3.1).
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 10.3.1).
10.3.2.3 REFERENCE and VALUE Properties
The following cDEC$ ATTRIBUTES properties specify how a dummy argument is to be passed:
Character values, substrings, and arrays cannot be passed by value. When REFERENCE is specified for a character argument, the string is passed with no descriptor.
VALUE is the default if the C property is specified in the subprogram definition (for scalar data only).
Consider the following free-form example, which passes an integer by value:
interface subroutine foo (a) !DEC$ ATTRIBUTES value :: a integer a end subroutine foo end interface |
This subroutine can be invoked from Compaq Fortran using the name foo:
integer i i = 1 call foo(i) end program |
This is the actual subroutine code:
subroutine foo (i) !DEC$ ATTRIBUTES value :: i integer i i = i + 1 . . end subroutine foo |
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.
10.3.2.5 ADDRESS64 Property
Specifies that the object has a 64-bit address. This property can be specified for any variable or dummy argument, including ALLOCATABLE and deferred-shape arrays. However, variables with this property cannot be data-initialized.
It can also be specified for COMMON blocks or for variables in a COMMON block. If specified for a COMMON block variable, the COMMON block implicitly has the ADDRESS64 property.
ADDRESS64 is not compatible with the AUTOMATIC attribute.
For More Information:
Programs compiled by the Compaq Fortran compiler conform to the standard defined for OpenVMS Alpha procedure calls (see the OpenVMS Programming Interfaces: Calling a System Routine and OpenVMS Calling Standard). This standard prescribes how registers and the system-maintained call stack can be used, how function values are returned, how arguments are passed, and how procedures receive and return control.
When writing routines that can be called from Compaq Fortran programs,
you should give special consideration to the argument list descriptions
in Section 10.4.3.
10.4.1 Register and Stack Usage
The Alpha architecture provides 32 general purpose integer registers (R0-R31) and 32 floating-point registers (F0-F31), each 64 bits in length. The OpenVMS Programming Interfaces: Calling a System Routine defines the use of these registers, as listed in Table 10-2.
Register | Use |
---|---|
R0 | Function value return registers; also see F0, F1 |
R1 | Conventional scratch register |
R2-R15 | Conventional saved registers |
R16-R21 | Argument registers (one register per argument, additional arguments are placed on the stack) |
R22-R24 | Conventional scratch registers |
R25 | Argument information (AI); contains argument count and argument type |
R26 | Return address (RA) register |
R27 | Procedure value (PV) register |
R28 | Volatile scratch register |
R29 | Frame pointer (FP) |
R30 | Stack pointer (SP) |
R31 | Read As Zero/Sink (RZ) register |
PC | Program counter (PC), a special register that addresses the instruction stream, which is not accessible as an integer register |
F0, F1 | Function value return registers (F1 is used for the imaginary part of COMPLEX) |
F2-F9 | Conventional saved registers |
F10-F15 | Conventional scratch registers |
F16-F21 | Argument registers (one per argument, additional arguments are placed on the stack) |
F22-F30 | Conventional scratch registers |
F31 | Read As Zero/Sink (RZ) register |
A stack is defined as a LIFO (last-in/first-out) temporary storage area that the system allocates for every user process.
Each time you call a routine, the system places information on the
stack in the form of procedure context structures, as described in
OpenVMS Calling Standard.
10.4.2 Return Values of Procedures
A procedure is a Compaq Fortran subprogram that performs one or more computations for other programs. Procedures can be either functions or subroutines. Both functions and subroutines can return values by storing them in variables specified in the argument list or in common blocks.
A function, unlike a subroutine, can also return a value to the calling program by assigning the value to the function's name. The method that function procedures use to return values depends on the data type of the value, as summarized in Table 10-3.
Data Type | Return Method |
---|---|
|
R0 |
REAL (KIND=4) | F0 |
REAL (KIND=8) | F0 |
REAL (KIND=16) | F0 and F1 |
COMPLEX (KIND=4)
(COMPLEX*8) |
F0 (real part), F1 (imaginary part) |
COMPLEX (KIND=8)
(COMPLEX*16) |
F0 (real part), F1 (imaginary part) |
Character | In addition to the arguments, an entry is added to the beginning of the argument list. This additional entry contains the address of the character string descriptor. At run time, before the call, the calling program allocates enough storage to contain the result and places the storage address in the descriptor. |
Pointers | R0 contains the address of the array descriptor (see Section 10.1.6). |
Assumed-shape arrays,
Deferred-shape arrays |
R0 contains the address of the array descriptor (see Section 10.1.5). |
For More Information:
Use an argument list to pass information to a routine and receive results.
The OpenVMS Calling Standard defines an argument list as an argument item sequence, consisting of the first six arguments occupying six integer and six floating-point registers (R16-R21 and F16-F21), with additional arguments placed on the stack. The argument information is contained in R25 (AI register). The stack pointer is contained in R30. For more details on argument lists, see the OpenVMS Calling Standard.
Memory for Compaq Fortran argument lists and for OpenVMS Alpha descriptors is allocated dynamically on the stack.
OpenVMS Alpha descriptors are generated from the use of the %DESCR function or by passing CHARACTER data, Fortran 90 pointers, and certain types of arrays (see Section 10.1.7).
Omitted arguments---for example, CALL X(A, ,B)---are represented by an argument passed by value that has a value of zero. This is a Compaq extension to the Fortran 90 standard.
Fortran optional arguments (OPTIONAL attribute) are also represented by an argument passed by value that has a value of zero.
For More Information:
On using Fortran language standards to specify arguments, see the
Compaq Fortran Language Reference Manual.
10.5 OpenVMS System Routines
System routines are OpenVMS routines that perform common tasks, such as finding the square root of a number or allocating virtual memory. You can call any system routine from your program, provided that Compaq Fortran supports the data structures required to call the routine (in a FORSYSDEF library module) or you define them yourself.
The system routines used most often are OpenVMS Run-Time Library
routines and system services. System routines are documented in detail
in the OpenVMS Run-Time Library Routines Volume and the
OpenVMS System Services Reference Manual.
10.5.1 OpenVMS Run-Time Library Routines
The OpenVMS Run-Time Library provides commonly-used routines that perform a wide variety of functions. These routines are grouped according to the types of tasks they perform, and each group has a prefix that identifies those routines as members of a particular OpenVMS Run-Time Library facility. Table 10-4 lists all of the language-independent Run-Time Library facility prefixes and the types of tasks each facility performs.
Facility Prefix | Types of Tasks Performed |
---|---|
CVT$ | Library routines that handle floating-point data conversion |
DTK$ | DECtalk routines that are used to control Compaq's DECtalk device |
LIB$ |
Library routines that:
|
MATH$ | Mathematics routines that perform arithmetic, algebraic, and trigonometric calculations |
OTS$ | General-purpose routines that perform such tasks as data type conversions as part of a compiler's generated code |
PPL$ | Parallel processing routines that help you implement concurrent programs on single-CPU and multiprocessor systems |
SMG$ | Screen-management routines that are used in designing, composing, and keeping track of complex images on a video screen |
STR$ | String manipulation routines that perform such tasks as searching for substrings, concatenating strings, and prefixing and appending strings |
System services are system routines that perform a variety of tasks, such as controlling processes, communicating among processes, and coordinating I/O.
Unlike the OpenVMS Run-Time Library routines, which are divided into groups by facility, all system services share the same facility prefix (SYS$). However, these services are logically divided into groups that perform similar tasks. Table 10-5 describes these groups.
Group | Types of Tasks Performed |
---|---|
AST | Allows processes to control the handling of ASTs |
Change Mode | Changes the access mode of particular routines |
Condition Handling | Designates condition handlers for special purposes |
Event Flag | Clears, sets, reads, and waits for event flags, and associates with event flag clusters |
Input/Output | Performs I/O directly, without going through OpenVMS RMS |
Lock Management | Enables processes to coordinate access to shareable system resources |
Logical Names | Provides methods of accessing and maintaining pairs of character string logical names and equivalence names |
Memory Management | Increases or decreases available virtual memory, controls paging and swapping, and creates and accesses shareable files of code or data |
Process Control | Creates, deletes, and controls execution of processes |
Process Information | Returns information about processes |
Security | Enhances the security of OpenVMS systems |
Timer and Time Conversion | Schedules events, and obtains and formats binary time values |
The basic steps for calling routines are the same whether you are calling a routine written in Compaq Fortran, a routine written in some other OpenVMS language, a system service, or a Compaq Fortran RTL routine.
To call a subroutine, use the CALL statement.
To call a function, reference the function name in an expression or as an argument in another routine call.
In any case, you must specify the name of the routine being called and all non-optional arguments required for that routine. Make sure the data types and passing mechanisms for the actual arguments you are passing coincide with those declared in the routine (see Table 10-6 for information on OpenVMS data types or OpenVMS Programming Interfaces: Calling a System Routine for data types needed for mixed language programming).
If you do not want to specify a value for a required parameter, you can pass a null argument by inserting a comma (,) as a placeholder in the argument list. If the routine requires any passing mechanism other than the default, you must specify the passing mechanism in the CALL statement or the function call.
Example 10-3 shows an example that uses the LIB$GET_VM RTL routine and the Compaq Fortran 77 POINTER statement to allocate memory for an array. This example uses Compaq extensions (POINTER statement and LIB$ routine) to allocate virtual memory. The routine name varies with the operating system (LIB$GET_VM on OpenVMS systems and malloc on UNIX systems).
Example 10-3 illustrates calling an OpenVMS RTL LIB$ routine.
Example 10-3 Use of LIB$GET_VM and POINTER |
---|
! Program accepts an integer and displays square root values INTEGER (KIND=4) N READ (5,*) N ! Request typed integer value CALL MAT(N) END ! Subroutine MAT uses the typed integer value to display the square ! root values of numbers from 1 to N (the typed number) SUBROUTINE MAT(N) REAL I(1000) ! Fixed 1000 dimension allows bounds checking INTEGER SIZE,STATUS POINTER (P,I) ! Compaq Fortran 77 POINTER statement establishes ! P as the pointer and array variable I as the ! pointee. P will receive memory base address ! from LIB$GET_VM. SIZE=SIZEOF(I(1)) * N ! Array I contains values calculated in loop below. ! Intrinsic SIZEOF returns size of memory ! to allocate. STATUS = LIB$GET_VM(SIZE,P) ! Allocate memory IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) DO J=1,N I(J) = SQRT(FLOAT(J)) ! Intrinsic FLOAT converts integer to REAL. ENDDO TYPE *, (I(J),J=1,N) ! Display calculated values STATUS = LIB$FREE_VM(SIZE,P) ! Deallocate memory IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) END SUBROUTINE MAT |
The following commands show how to compile, link, and run the program and how it displays the square root of numbers from 1 to 4 during execution:
$ FORTRAN SQUARE_ROOT $ LINK SQUARE_ROOT $ RUN SQUARE_ROOT 4 1.000000 1.414214 1.732051 2.000000 |
The call to LIB$GET_VM as a function reference allocates memory and returns the starting address in variable P. The return status (variable STATUS) is tested to determine whether an error should be signaled using a subroutine call to LIB$SIGNAL, passing the value of the variable status (not its address) using the %VAL built-in function.
For More Information:
Previous | Next | Contents | Index |