HP OpenVMS Systems Documentation

Content starts here

HP Fortran for OpenVMS
User Manual


Previous Contents Index

10.8.4.5 Examples of Passing Arguments

Example 10-4 shows a complete subroutine that uses a data structure argument to the SYS$GETJPIW system service.

Example 10-4 Subroutine Using a Data Structure Argument

!  Subroutine to obtain absolute and incremental values of process parameters:
!  CPU time, Buffered I/O count, Direct I/O count, Page faults.

      SUBROUTINE PROCESS_INFO(ABS_VALUES, INCR_VALUES)

!  Declare the arguments and working storage

      INTEGER (KIND=4) ABS_VALUES(4), INCR_VALUES(4), LCL_VALUES(4)
      INTEGER (KIND=4) STATUS, I

!  Declare the SYS$GETJPIW item list data structure in a structure declaration

      STRUCTURE /GETJPI_STR/
              INTEGER (KIND=2)  BUFLEN /4/, ITMCOD /0/
              INTEGER (KIND=4)  BUFADR, RETLEN /0/
      END STRUCTURE

!  Create a record with the fields defined in the structure declaration

      RECORD /GETJPI_STR/ LIST(5)

!  Declare the structure of an I/O Status Block

      STRUCTURE /IOSB_STR/
           INTEGER (KIND=4) STATUS, RESERVED
      END STRUCTURE

!  Declare the I/O Status Block

      RECORD /IOSB_STR/ IOSB

!  Assign all static values in the item list

      LIST(1).ITMCOD = JPI$_CPUTIM
      LIST(2).ITMCOD = JPI$_BUFIO
      LIST(3).ITMCOD = JPI$_DIRIO
      LIST(4).ITMCOD = JPI$_PAGEFLTS

!  Assign all item fields requiring addresses

      LIST(1).BUFADR = %LOC(LCL_VALUES(1))
      LIST(2).BUFADR = %LOC(LCL_VALUES(2))
      LIST(3).BUFADR = %LOC(LCL_VALUES(3))
      LIST(4).BUFADR = %LOC(LCL_VALUES(4))

      STATUS = SYS$GETJPIW(,,,LIST,IOSB,,)  ! Perform system service call

      IF (STATUS) STATUS = IOSB.STATUS      ! Check completion status
      IF (.NOT. STATUS) CALL EXIT (STATUS)

!  Assign the new values to the arguments

      DO I=1,4
         INCR_VALUES(I) = LCL_VALUES(I) - ABS_VALUES(I)
         ABS_VALUES(I)  = LCL_VALUES(I)
      END DO
      RETURN

      END SUBROUTINE PROCESS_INFO

Example 10-5 is an example of the typical use of an I/O system service. The program invokes SYS$QIOW to enable Ctrl/C trapping. When the program runs, it prints an informational message whenever it is interrupted by a Ctrl/C, and then it continues execution.

Example 10-5 Ctrl/C Trapping Example

   PROGRAM TRAPC
   INCLUDE '($SYSSRVNAM)'
   INTEGER (KIND=2) TT_CHAN
   COMMON TT_CHAN
   CHARACTER (LEN=40) LINE

!  Assign the I/O channel.  If unsuccessful stop; otherwise
!  initialize the trap routine.

   ISTAT = SYS$ASSIGN ('TT',TT_CHAN,,)
   IF (.NOT. ISTAT) CALL LIB$STOP(%VAL(ISTAT))
   CALL ENABLE_CTRLC

!     Read a line of input and echo it

 10 READ (5,'(A)',END=999) LINE
    TYPE *, 'LINE READ: ', LINE
    GO TO 10
999 END

    SUBROUTINE ENABLE_CTRLC
    INTEGER (KIND=2) TT_CHAN
    COMMON TT_CHAN
    EXTERNAL CTRLC_ROUT

!   Include I/O symbols

    INCLUDE '($IODEF)'
    INCLUDE '($SYSSRVNAM)'

!     Enable Ctrl/C trapping and specify CTRLC_ROUT
!     as routine to be called when Ctrl/C occurs

    ISTAT = SYS$QIOW( ,%VAL(TT_CHAN), %VAL(IO$_SETMODE .OR. IO$M_CTRLCAST),&
        ,,,CTRLC_ROUT,,%VAL(3),,,)
    IF (.NOT. ISTAT) CALL LIB$STOP(%VAL(ISTAT))
    RETURN
    END SUBROUTINE ENABLE_CTRLC

    SUBROUTINE CTRLC_ROUT
    PRINT *, 'Ctrl/C pressed'
    CALL ENABLE_CTRLC
    RETURN

    END SUBROUTINE CTRLC_ROUT

For more examples of calling system services and RTL routines, see Appendix F and the HP Fortran Web site.

10.9 Calling Between Compaq Fortran 77 and HP Fortran

On OpenVMS Alpha systems, you can call a Compaq Fortran 77 subprogram from HP Fortran or call an HP Fortran subprogram from Compaq Fortran 77 (with very few exceptions). A Compaq Fortran 77 procedure and a HP Fortran procedure can also perform I/O to the same unit number.

10.9.1 Argument Passing and Function Return Values

The recommended rules for passing arguments and function return values between Compaq Fortran 77 and HP Fortran procedures are as follows:

  • If possible, express the following HP Fortran features with the Compaq Fortran 77 language:
    • Function references
    • CALL statements
    • Function definitions
    • Subroutine definitions

    Avoid using HP Fortran language features not available in Compaq Fortran 77. Since HP Fortran is a superset of Compaq Fortran 77, specifying the procedure interface using the Compaq Fortran 77 language helps ensure that calls between the two languages will succeed.
  • Not all data types in HP Fortran have equivalent Compaq Fortran 77 data types. The following HP Fortran features should not be used between HP Fortran and Compaq Fortran 77 procedures, because they are not supported by Compaq Fortran 77:
    • Derived-type (user-defined) data, which has no equivalents in Compaq Fortran 77.
      HP Fortran record structures are supported by Compaq Fortran 77 and HP Fortran as an extension to the Fortran 90 standard. Thus, you can use Compaq Fortran 77 record structures in both HP Fortran and Compaq Fortran 77.
    • HP Fortran data with the POINTER attribute, which has no equivalents in Compaq Fortran 77. The pointer data type supported by Compaq Fortran 77 is not equivalent to Fortran 90 pointer data.
      Because HP Fortran supports the pointer data type supported by Compaq Fortran 77, you can use Compaq Fortran 77 pointer data types in both HP Fortran and Compaq Fortran 77. (In some cases, you can create Compaq Fortran 77 pointer data in an HP Fortran procedure using the %LOC function.)
      HP Fortran arrays with the POINTER attribute are passed by array descriptor. A program written in Compaq Fortran 77 needs to interpret the array descriptor format generated by an HP Fortran array with the POINTER attribute (see Section 10.2.7).
    • HP Fortran assumed-shape arrays.
      HP Fortran assumed-shape arrays are passed by array descriptor. A program written in Compaq Fortran 77 needs to interpret the array descriptor format generated by an HP Fortran assumed-shape array (see Section 10.2.7).

    For more information on how HP Fortran handles arguments and function return values, see Section 10.2.4.
  • Make sure the sizes of INTEGER, LOGICAL, REAL, and COMPLEX declarations match.
    For example, HP Fortran declarations of REAL (KIND=4) and INTEGER (KIND=4) match Compaq Fortran 77 declarations of REAL*4 and INTEGER*4. For COMPLEX values, an HP Fortran declaration of COMPLEX (KIND=4) matches a Compaq Fortran 77 declaration of COMPLEX*8; COMPLEX (KIND=8) matches COMPLEX*16.
    Your source programs may contain INTEGER, LOGICAL, REAL, or COMPLEX declarations without a kind parameter (or size specifier). In this case, when compiling the HP Fortran procedures (FORTRAN command) and Compaq Fortran 77 procedures (FORTRAN/OLDF77 command), either omit or specify the equivalent qualifiers for controlling the sizes of these declarations.
    For more information on these qualifiers, see Section 2.3.26 for INTEGER and LOGICAL declarations, Section 2.3.37 for REAL and COMPLEX declarations, and Section 2.3.17 for DOUBLE PRECISION declarations.
  • HP Fortran uses the same argument-passing conventions as Compaq Fortran 77 on OpenVMS Alpha systems (see Section 10.2.4).
  • You can return nearly all function return values from an HP Fortran function to a calling Compaq Fortran 77 routine, with the following exceptions:
    • You cannot return HP Fortran pointer data from HP Fortran to a Compaq Fortran 77 calling routine.
    • You cannot return HP Fortran user-defined data types from an HP Fortran function to a Compaq Fortran 77 calling routine.

Example 10-6 and Example 10-7 show passing an array from an HP Fortran program to a Compaq Fortran 77 subroutine that prints its value.

Example 10-6 shows the HP Fortran program (file ARRAY_TO_F77.F90). It passes the same argument as a target and a pointer. In both cases, it is received by reference by the Compaq Fortran 77 subroutine as a target (regular) argument. The interface block in Example 10-6 is not needed, but does allow data type checking.

Example 10-6 HP Fortran Program Calling a Compaq Fortran 77 Subroutine

 ! Pass arrays to f77 routine. File: ARRAY_TO_F77.F90

 ! This interface block is not required, but must agree
 ! with actual procedure. It can be used for type checking.

 INTERFACE                    ! Procedure interface block
   SUBROUTINE MEG(A)
   INTEGER :: A(3)
   END SUBROUTINE
 END INTERFACE

 INTEGER, TARGET :: X(3)
 INTEGER, POINTER :: XP(:)

 X = (/ 1,2,3 /)
 XP => X

 CALL MEG(X)                  ! Call f77 implicit interface subroutine twice.
 CALL MEG(XP)
 END

Example 10-7 shows the Compaq Fortran 77 program called by the HP Fortran program (file ARRAY_F77.FOR).

Example 10-7 Compaq Fortran 77 Subroutine Called by an HP Fortran Program

! Get array argument from F90. File: ARRAY_F77.FOR

 SUBROUTINE MEG(A)
 INTEGER A(3)
 PRINT *,A
 END

These files (shown in Example 10-6 and Example 10-7) might be compiled, linked, and run as follows:


$ FORTRAN ARRAY_TO_F77.F90
$ FORTRAN /OLD_F77 ARRAY_F77.FOR
$ LINK/EXECUTABLE=ARRAY_TO_F77 ARRAY_TO_F77, ARRAY_F77
$ RUN ARRAY_TO_F77
           1           2           3
           1           2           3

In Example 10-6, because array A is not defined as a pointer in the interface block, the HP Fortran pointer variable XP is passed as target data by reference (address of the target data).

However, if the interface to the dummy argument had the POINTER attribute, the variable XP would be passed by descriptor. This descriptor would not work with the Compaq Fortran 77 program shown in Example 10-7.

For More Information:

  • On how HP Fortran handles arguments and function return values, see Section 10.2.4.
  • On explicit interfaces, see the HP Fortran for OpenVMS Language Reference Manual.
  • On compatibility between the HP Fortran and Compaq Fortran 77 languages, see Appendix B.
  • On use association, see the HP Fortran for OpenVMS Language Reference Manual.
  • On other aspects of the HP Fortran language, see the HP Fortran for OpenVMS Language Reference Manual.
  • On calling the Fortran 77 compiler with the /OLD_F77 compiler option, see Section 2.3.34.

10.9.2 Using Data Items in Common Blocks

To make global data available across HP Fortran and Compaq Fortran 77 procedures, use common blocks.

Common blocks are supported by both HP Fortran and Compaq Fortran 77, but modules are not supported by Compaq Fortran 77. Some suggestions about using common blocks follow:

  • Use the same COMMON statement to ensure that the data items match in order, type, and size.
    If multiple HP Fortran procedures will use the same common block, declare the data in a module and reference that module with a USE statement where needed.
    If Compaq Fortran 77 procedures use the same common block as the HP Fortran procedures and the common block is declared in a module, consider modifying the Compaq Fortran 77 source code as follows:
    • Replace the common block declaration with the appropriate USE statement.
    • Recompile the Compaq Fortran 77 source code with the FORTRAN command (HP Fortran compiler).
  • Specify the same alignment characteristics with the /ALIGNMENT qualifier when compiling both HP Fortran procedures (FORTRAN command) and Compaq Fortran 77 procedures (FORTRAN/OLDF77 command).
    When compiling the source files with both the FORTRAN and FORTRAN/OLDF77 commands, consistently use the /ALIGN=COMMONS qualifier. This naturally aligns data items in a common block and ensures consistent format of the common block.
  • Make sure the sizes of INTEGER, LOGICAL, REAL, and COMPLEX declarations match.
    For example, HP Fortran declarations of REAL (KIND=4) and INTEGER (KIND=4) match Compaq Fortran 77 declarations of REAL*4 and INTEGER*4. For COMPLEX values, an HP Fortran declaration of COMPLEX (KIND=4) matches a Compaq Fortran 77 declaration of COMPLEX*8; COMPLEX (KIND=8) matches COMPLEX*16.
    Your source programs may contain INTEGER, LOGICAL, REAL, or COMPLEX declarations without a kind parameter or size specifier. In this case, either omit or specify the same qualifiers that control the sizes of these declarations when compiling the procedures with multiple commands (same rules as Section 10.9.1).

10.9.3 I/O to the Same Unit Number

HP Fortran and Compaq Fortran 77 share the same run-time system, so you can perform I/O to the same unit number by HP Fortran and Compaq Fortran 77 procedures. For instance, a HP Fortran main program can open the file, a Compaq Fortran 77 function can issue READ or WRITE statements to the same unit, and the HP Fortran main program can close the file.

For More Information:

  • On the HP Fortran language, see the HP Fortran for OpenVMS Language Reference Manual.
  • On passing arguments, function return values, and the contents of registers on OpenVMS systems, see the HP OpenVMS Calling Standard.
  • On HP Fortran intrinsic data types, see Chapter 8.
  • On HP Fortran I/O, see Chapter 6.

10.10 Calling Between HP Fortran and HP C

Before creating a mixed-language program that contains procedures written in HP Fortran and C, you need to know how to:

  • Compile and link the program
  • Use equivalent data arguments passed between the two languages

10.10.1 Compiling and Linking Files

Use the FORTRAN command to compile HP Fortran source files and CC to compile C source files. Link the object files using a LINK command.

For example, the following FORTRAN command compiles the HP Fortran main program EX1.F90 and the called C function UPEN.C:


$ FORTRAN EX1.F90 
$ CC UPEN.C

The following LINK command creates the executable program:


$ LINK EX1, UPEN

10.10.2 Procedures and External Names

When designing a program that will use HP Fortran and C, be aware of the following general rules and available HP Fortran capabilities:

  • The OpenVMS Linker only allows one main program. Declare either the HP Fortran or the C program, but not both, as the main program.
    In HP Fortran, you can declare a main program:
    • With the PROGRAM and END PROGRAM statements
    • With an END statement

    To create a HP Fortran subprogram, declare the subprogram with such statements as FUNCTION and END FUNCTION or SUBROUTINE and END SUBROUTINE.
    In C, you need to use a main() declaration for a main program. To create a C function (subprogram), declare the appropriate function name and omit the main() declaration.
  • External names in C and HP Fortran are usually converted to uppercase.
    Because both HP Fortran and C make external names uppercase by default, external names should be uppercase unless requested otherwise.
    Consistently use the CC qualifier /NAMES and the FORTRAN qualifier /NAMES to control the way C and HP Fortran treat external names (see Section 2.3.32).
  • You can consider using the following HP Fortran facility provided to simplify the HP Fortran and C language interface.
    You can use the cDEC$ ALIAS and cDEC$ ATTRIBUTES directives to specify alternative names for routines and change default passing mechanisms (see Section 10.4).

10.10.3 Invoking a C Function from HP Fortran

You can use a function reference or a CALL statement to invoke a C function from an HP Fortran main or subprogram.

If a value will be returned, use a function reference:

C Function Declaration HP Fortran Function Invocation
data-type calc( argument-list)
{
...
} ;
EXTERNAL CALC
data-type :: CALC, variable-name
...
variable-name=CALC( argument-list)
...

If no value is returned, use a void return value and a CALL statement:

C Function Declaration HP Fortran Subroutine Invocation
void calc( argument-list)
{
...
} ;
EXTERNAL CALC
...
CALL CALC( argument-list)

10.10.4 Invoking an HP Fortran Function or Subroutine from C

A C main program or function can invoke an HP Fortran function or subroutine by using a function prototype declaration and invocation.

If a value is returned, use a FUNCTION declaration:

HP Fortran Declaration C Invocation
FUNCTION CALC( argument-list)
data-type :: CALC
...
END FUNCTION CALC
extern data-type calc( argument-list)
data-type variable-name;
variable-name=calc( argument-list);
...

If no value is returned, use a SUBROUTINE declaration and a void return value:

HP Fortran Declaration C Invocation
SUBROUTINE CALC( argument-list)
...
END SUBROUTINE CALC
extern void calc( argument-list)

calc( argument-list);
...

10.10.5 Equivalent Data Types for Function Return Values

Both C and HP Fortran pass most function return data by value, but equivalent data types must be used. The following table lists a sample of equivalent function declarations in HP Fortran and C. See Table 10-8 for a complete list of data declarations.

C Function Declaration HP Fortran Function Declaration
float rfort() FUNCTION RFORT()
REAL (KIND=4) :: RFORT
double dfort() FUNCTION DFORT()
REAL (KIND=8) :: DFORT
int ifort() FUNCTION IFORT()
INTEGER (KIND=4) :: IFORT

Because there are no corresponding data types in C, you should avoid calling HP Fortran functions of type COMPLEX and DOUBLE COMPLEX, unless you pass a struct of two float (or double float) C values (see Section 10.10.9).

The floating-point format used in memory is determined by the /FLOAT qualifier for both the FORTRAN and CC commands. When floating-point data is passed as an argument or is globally available, the same floating-point format must be used in memory by both the C and HP Fortran parts of your program.

The HP Fortran LOGICAL data types contain a zero if the value is false and a --1 if the value is true, which works with C conditional and if statements.

For More Information:

  • On using the CC command, see the HP C User's Guide for OpenVMS Systems.
  • On using the FORTRAN command, see Chapter 2.
  • On HP Fortran intrinsic data types, see Chapter 8.
  • On the HP Fortran language, see the HP Fortran for OpenVMS Language Reference Manual.
  • On the HP C language, see the HP C Language Reference Manual.

10.10.6 Argument Association and Equivalent Data Types

HP Fortran follows the argument-passing rules described in Section 10.2.4. These rules include:

  • Passing arguments by reference (address)
  • Receiving arguments by reference (address)
  • Passing character data using a character descriptor (address and length)

10.10.6.1 HP Fortran Intrinsic Data Types

HP Fortran lets you specify the lengths of its intrinsic numeric data types with the following:

  • The kind parameter, such as REAL (KIND=4), which is sometimes abbreviated as REAL(4). Intrinsic integer and logical kinds are 1, 2, 4, and 8. Intrinsic real and complex kinds are 4 (single-precision) and 8 (double-precision).
  • A default-length name without a kind parameter, such as REAL or INTEGER. Certain FORTRAN command qualifiers can change the default kind, as described in Section 2.3.26 (for INTEGER and LOGICAL declarations), Section 2.3.37 (for REAL and COMPLEX declarations), and Section 2.3.17 (for DOUBLE PRECISION declarations).
  • The HP Fortran extension of appending a *n size specifier to the default-length name, such as INTEGER*8.
  • For double-precision real or complex data, the word DOUBLE followed by the default-length name without a kind parameter (specifically DOUBLE PRECISION and DOUBLE COMPLEX).

The following declarations of the integer An are equivalent (unless you specified the appropriate FORTRAN command qualifier):


INTEGER (KIND=4) :: A1
INTEGER (4)      :: A2
INTEGER          :: A3
INTEGER*4        :: A4

Character data in HP Fortran is passed and received by character descriptor. Dummy character arguments can use assumed-length for accepting character data of varying length.

For More Information:

On HP Fortran intrinsic data types, see Chapter 8.


Previous Next Contents Index