[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

HP Fortran for OpenVMS
User Manual


Previous Contents Index

10.2.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 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:

  • Pointers to arrays (array pointers)
  • Assumed-shape arrays

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:

  • 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 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 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, HP 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 HP Fortran program was compiled with /BY_REF_CALL).

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:

  • %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 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.

For More Information:

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.

For More Information:

  • On declaring volatile data structures, see the HP Fortran for OpenVMS 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.3.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:


%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.

For More Information:

  • On intrinsic procedures, see the HP Fortran for OpenVMS 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.10.7.
  • On the ZEXT intrinsic function, see HP Fortran for OpenVMS Language Reference Manual.
  • On the %VAL built-in function, see the HP Fortran for OpenVMS Language Reference Manual.

10.3.4 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 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.

  1. In this example, the first constant is passed by reference. The second constant is passed by immediate value:


      CALL SUB(2,%VAL(2))
    
  2. In this example, the first character variable is passed by character descriptor. The second character variable is passed by reference:


      CHARACTER(LEN=10) A,B
      CALL SUB(A,%REF(B))
    
  3. In this example, the first array is passed by reference. The second array is passed by descriptor:


      INTEGER IARY(20), JARY(20)
      CALL SUB(IARY,%DESCR(JARY))
    

10.4 Using the cDEC$ ALIAS and cDEC$ ATTRIBUTES Directives

This section provides reference information about the following directives:

  • The cDEC$ ALIAS (or !DEC$ ALIAS or *DEC$ ALIAS) directive allows you to specify a name for an external subprogram that differs from the name used by the calling subprogram.
  • The cDEC$ ATTRIBUTES (or !DEC$ ATTRIBUTES or *DEC$ ATTRIBUTES) directive allows you to specify the properties for external data objects and procedures. This includes using C language rules, specifying how an argument is passed (passing mechanism), and specifying an alias for an external routine.

10.4.1 The cDEC$ ALIAS Directive

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:

10.4.2.1 C Property

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.

Table 10-1 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 (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:

  • If C is specified without REFERENCE for the arguments, the first character of the string is passed (padded with zeros out to INTEGER*4 length).
  • If C is specified with REFERENCE for the argument (or if only REFERENCE is specified), the starting address of the string is passed with no descriptor.

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

10.4.2.2 ALIAS Property

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:

  • REFERENCE specifies a dummy argument's memory location is to be passed, not the argument's value.
  • VALUE specifies a dummy argument's value is to be passed, not the argument's memory location.

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