HP OpenVMS Systems Documentation |
HP Fortran for OpenVMS
|
Previous | Contents | Index |
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:
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.
On using pointers and pointer arguments, see the HP Fortran for OpenVMS Language Reference Manual.
10.2.7 HP Fortran Array Descriptor Format
When using an explicit interface (by association or procedure interface block), HP Fortran will generate a descriptor for the following types of dummy argument data structures:
To allow calling between Compaq Fortran 77 and HP 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 HP Fortran, an array descriptor is not used.
When calling between HP 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 HP Fortran is the OpenVMS Noncontiguous Array Descriptor as described in the HP 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:
For information about the Noncontiguous Array Descriptor when 64-bit
addressing is requested (cDEC$ ATTRIBUTES ADDRESS64 directive), see the
HP OpenVMS Calling Standard.
10.3 Argument-Passing Mechanisms and Built-In Functions
The OpenVMS procedure-calling standard defines three mechanisms by which arguments are passed to procedures:
By default, HP Fortran uses the reference and descriptor mechanisms to pass arguments, depending on each argument's data type:
When an HP 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 HP 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, HP 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:
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 HP Fortran.
The use of these functions in system service calls is described in Section 10.8.4. The sections that follow describe their use in general.
Instead of using the HP Fortran built-in functions, you can use the
cDEC$ ATTRIBUTES directive to change the HP Fortran default passing
mechanisms (see Section 10.4.2).
10.3.1 Passing Arguments by Descriptor---%DESCR Function
The %DESCR function passes its argument by descriptor. It has the following form:
%DESCR(arg) |
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 HP 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. HP Fortran always generates code to refer to character dummy arguments through the addresses in their character descriptors.
On HP Fortran array descriptors, see Section 10.2.7.
10.3.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:
%LOC(arg) |
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.
The %VAL function passes the argument list entry as a 64-bit immediate value. It has the following form:
%VAL(arg) |
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.
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 HP Fortran, passing
by reference is the default mechanism for numeric values, so the %REF
call is usually not needed.
10.3.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:
HP 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 HP 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.4.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 HP Fortran routines written in C or Assembler.
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 HP Fortran for OpenVMS Language Reference Manual. )
att
Is one of the keywords listed in the HP Fortran for OpenVMS Language Reference Manual. For example, C, ALIAS, REFERENCE, VALUE, EXTERN, VARYING, and ADDRESS64
object
Is the name of a data object used as an argument or procedure. Only one object is allowed when using the C and ALIAS properties.
The HP Fortran for OpenVMS 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 HP 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 HP 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.4.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.4.1).
10.4.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 HP 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 |
Previous | Next | Contents | Index |