Compaq Fortran
User Manual for
Tru64 UNIX and Linux Alpha Systems


Previous Contents Index

11.4.9 Example of Passing Complex Data to C Functions

Example 11-9 shows Compaq Fortran code that passes a COMPLEX (KIND=4) value (1.0,0.0) by immediate value to subroutine foo. To pass COMPLEX arguments by value, the compiler passes the real and imaginary parts of the argument as two REAL arguments by immediate value.

Example 11-9 Calling C Functions and Passing Complex Arguments

 
  ! Using !DEC$ATTRIBUTES to pass COMPLEX argument by value to F90 or C. 
  ! File: cv_main.f90  
 
  interface 
     subroutine foo(cplx) 
       !DEC$ATTRIBUTES C :: foo 
          complex cplx 
     end subroutine 
  end interface 
 
    complex(kind=4) c 
    c = (1.0,0.0) 
    call foo(c)             ! pass by value 
 
  end 

If subroutine foo were written in Compaq Fortran, it might look similar to the following example. In this version of subroutine foo, the COMPLEX parameter is received by immediate value. To accomplish this, the compiler accepts two REAL parameters by immediate value and stores them into the real and imaginary parts, respectively, of the COMPLEX parameter cplx.


  ! File: cv_sub.f90  
 
     subroutine foo(cplx) 
       !DEC$ATTRIBUTES C :: foo 
       complex cplx 
 
       print *, 'The value of the complex number is ', cplx 
 
     end subroutine 

If subroutine foo were written in C, it might look similar to the following example in which the complex number is explicitly specified as two arguments of type float:


  /* File: cv_sub.c */ 
 
  #include <stdio.h> 
 
  typedef struct {float c1; float c2;} complex; 
 
  void foo(complex c) 
  { 
      printf("The value of the complex number is (%f,%f)\n", c.c1, c.c2); 
  } 

The main routine (shown in Example 11-9) might be compiled and linked to the object file created by the compilation of the Compaq Fortran subroutine and then run as follows:


 
% f90 -o cv cv_main.f90, cv_sub.f90
% cv
The value of the complex number is (1.000000,0.0000000E+00)

The main routine might also be compiled and linked to the object file created by the compilation of the C subroutine and then run as follows:


% cc -c cv_sub.c
% f90 -o cv2 cv_main.f90 cv_sub.f90
% cv2
The value of the complex number is (1.000000,0.000000)

11.4.10 Handling User-Defined Structures

User-defined derived types in Compaq Fortran and user-defined C structures can be passed as arguments if the following conditions are met:

11.4.11 Handling Scalar Pointer Data

When Compaq Fortran passes scalar numeric data with the pointer attribute, how the scalar numeric data gets passed depends on whether or not an interface block is provided:

When passing scalar numeric data without the pointer attribute, Compaq Fortran passes the actual data by reference. If the called C function declares the dummy argument for the passed data to be passed by a pointer, it accepts the actual data passed by reference (address) and handles it correctly.

Similarly, when passing scalar data from a C program to a Compaq Fortran subprogram, the C program can use pointers to pass numeric data by reference.

Example 11-10 shows a Compaq Fortran program that passes a scalar (nonarray) pointer to a C function. Variable x is a pointer to variable y.

The function call to ifunc1_ uses a procedure interface block, whereas the function call to ifunc2_ does not. Because ifunc1_ uses a procedure interface block (explicit interface) and the argument is given the pointer attribute, the pointer is passed. Without an explicit interface (ifunc2_) , the target data is passed.

Example 11-10 Calling C Functions and Passing Pointer Arguments

! Pass scalar pointer argument to C. File: scalar_pointer.f90 
 
interface 
  function ifunc1(a) 
  integer, pointer :: a 
  integer ifunc1 
  end function 
end interface 
 
integer, pointer :: x 
integer, target :: y 
 
y = 88 
x => y 
print *,ifunc1(x)           ! interface block visible, so pass 
                            ! pointer by reference. C expects "int **" 
 
print *,ifunc2(x)           ! no interface block visible, so pass 
                            ! value of "x" by reference. C expects "int *" 
print *,y 
end 

Example 11-11 shows the C function declarations that receive the Compaq Fortran pointer or target arguments from the example in Example 11-10.

Example 11-11 C Functions Receiving Pointer Arguments

/* C functions Fortran pointers. File: scalar_pointer.c  */ 
 
int ifunc1_(int **a) { 
    printf("a=%d\n",**a); 
    **a = 99; 
    return 100; 
    } 
 
int ifunc2_(int *a) { 
    printf("a=%d\n",*a); 
    *a = 77; 
    return 101; 
} 

The files (shown in Example 11-10 and Example 11-11) might be compiled, linked, and run as follows:


% cc -c  scalar_pointer.c
% f90 -o scalar_pointer scalar_pointer.f90 scalar_pointer.o
% scalar_pointer
a=88 
         100 
a=99 
         101 
          77 

11.4.12 Handling Arrays

There are two major differences between the way the C and Compaq Fortran languages handle arrays:

Because of these two factors:

Compaq Fortran orders arrays in column-major order. The following Compaq Fortran array declaration for a 2 by 3 array creates elements ordered as y(1,1), y(2,1), y(1,2), y(2,2), y(1,3), y(2,3):


integer y(2,3) 

The Compaq Fortran declaration for a 2 by 3 array can be modified as follows to have the lowest bound 0 and not 1, resulting in elements ordered as y(0,0), y(1,0), y(0,1), y(1,1), y(0,2), y(1,2):


integer y(0:1,0:2) 

The following C array declaration for a 3 by 2 array has elements in row-major order as z[0,0], z[0,1], z[1,0], z[1,1], z[2,0], z[2,1]:


int z[3][2] 

To use C and Compaq Fortran array data:

When passing certain array arguments, if you use an explicit interface that specifies the dummy argument as an array with the POINTER attribute or an assumed-shape array, the argument is passed by array descriptor (see Section 11.1.7).

For information about performance when using multidimensional arrays, see Section 5.4.

Example 11-12 shows a C function declaration for function expshape_ , which prints the passed explicit-shape array.

Example 11-12 C Function That Receives an Explicit-Shape Array

/* Get explicit-shape arrays from Fortran  */ 
 
void expshape_(int  x[3][2]) { 
    int i,j; 
  for (i=0;i<3;i++) 
     for (j=0;j<2;j++) printf("x[%d][%d]=%d\n",i,j,x[i][j]); 
} 

Example 11-13 shows a Compaq Fortran program that calls the C function expshape_ (shown in Example 11-12).

Example 11-13 Compaq Fortran Program That Passes an Explicit-Shape Array

! Pass an explicit-shape array from Fortran to C. 
 
integer :: x(2,3) 
x = reshape( (/(i,i=1,6)/), (/2,3/) ) 
 
call expshape(x) 
end 

The files (shown in Example 11-12 and Example 11-13) might be compiled, linked, and run as follows:


% cc -c  exparray.c
% f90 -o exparray exparray.f90 exparray.o
% exparray
x[0][0]=1 
x[0][1]=2 
x[1][0]=3 
x[1][1]=4 
x[2][0]=5 
x[2][1]=6 

For information on the use of array arguments with Compaq Fortran, see Section 11.1.5.

11.4.13 Handling Common Blocks of Data

The following notes apply to handling common blocks of data between Compaq Fortran and C:

The following examples show how C and Compaq Fortran code can access common blocks of data. The C code declares a global structure, calls the f_calc_ Compaq Fortran function to set the values, and prints the values:


struct S {int j; float k;}r_; 
main() { 
f_calc_(); 
printf("%d %f\n", r_.j, r_.k); 
} 

The Compaq Fortran function then sets the data values:


subroutine f_calc() 
common /r/j,k 
real k 
integer j 
j = 356 
k = 5.9 
return 
end 

The C program then prints the structure member values 356 and 5.9 set by the Compaq Fortran function.

The previous example applies to Compaq Tru64 UNIX systems. On Compaq Linux systems, the external names with one underscore would have two trailing underscores.

11.5 Calling Between Parallel HPF and Non-Parallel HPF Code

When calling between parallel HPF and non-parallel HPF code (TU*X ONLY), the -wsf and -nowsf_main compile-time options are required in certain cases, and prohibited in other cases. For more detailed information, see the Compaq Parallel Software Environment documentation.


Chapter 12
Compaq Fortran Library Routines

Compaq Fortran (Compaq Fortran) library routines consist of two groups of routines, commonly referred to by their Tru64 UNIX or Linux reference page section:

When you use the f90 command on Tru64 UNIX systems or the fort command on Linux systems to compile and link your program, ld automatically searches the object libraries in which the Compaq Fortran library routines reside.

When you use ld instead of f90 or fort to link object modules, specify the appropriate Compaq Fortran libraries with -l string option. The Compaq Fortran libraries are listed in Section 2.5.1.

12.1 Reference Pages for the 3f and 3hpf Routines

As indicated in Table 12-3, additional information is available in reference pages for the 3f (Fortran) routines. Also, intro(3f) provides a list of all the 3f routines.

In addition to the summary of each routine in the Compaq Fortran Language Reference Manual, detailed information is available in reference pages for the 3hpf routines. Also, intro(3hpf) lists the 3hpf routines.

You can use the man command to view online reference page information in the following ways:

12.2 EXTERNAL or INTRINSIC Declarations

Certain Compaq Fortran library routines have the same names as intrinsic functions or subroutines (subprograms). You need to make sure that the correct routine or intrinsic subprogram is used:

The following 3f routines have names that match similar intrinsic subprograms:
and
idate
index
len
lshift
not
or
rshift
time
xor

For portability reasons, you should consider using the intrinsic routines instead of the equivalent 3f external routine.

For More Information:

12.3 Types of Compaq Fortran 3f Library Routines

Compaq Fortran on Compaq Tru64 UNIX and Linux Alpha systems provides a collection of 3f library routines designed to be called from Compaq Fortran.

The 3f library routines differ from the standard Compaq Fortran intrinsic subprograms provided by Compaq Fortran and fall into two groups:

Table 12-1 lists the groups of language interface library routines.

Table 12-1 Language Interface 3f Library Routines
Category Routine Names Standard-Conforming Alternatives
Bessel mathematical operations besj0 , besj1 , besjn , besy0 , besy1 , besyn , dbesj0 , dbesj1 , dbesjn , dbesy0 , dbesy1 , dbesyn None.
Bit manipulation and , lshift , not , or , rshift , xor Consider using the Compaq Fortran intrinsics with the same name instead.
Directories and files access , chdir , chmod , fstat , flush , fsync , isatty , link , lstat , rename , stat , symlnk , ttynam , umask , unlink None.
Error handling gerror , ierrno , perror Use error-handling specifiers to handle Compaq Fortran errors, such as ERR and IOSTAT. Use these routines to handle Tru64 UNIX and Linux errors.
I/O fgetc , fputc , fseek , ftell , getc , putc Consider using Compaq Fortran nonadvancing I/O instead of fgetc , fputc , getc , putc .
Miscellaneous index , len , lnblnk , loc , long , qsort , rindex , short , system Instead of index and len , use the Compaq Fortran intrinsic functions INDEX and LEN.
Random numbers drandm , irand , irandm , rand , random , srand Consider using the Compaq Fortran intrinsic subroutines RANDOM_NUMBER and RANDOM_SEED.
Return date and time ctime , dtime , etime , fdate , gmtime , idate , itime , ltime , time Consider using the Compaq Fortran intrinsic subroutine DATE_AND_TIME or, if you need a subset of the information returned by DATE_AND_TIME, the intrinsic subroutines (Compaq extensions) DATE, IDATE, and TIME.
Return error function erf , derf , erfc , derfc None.
Return process, system, or command-line information getarg , getcwd , getenv , getgid , getlog , getpid , getuid , iargc None.
Signals and processes abort , alarm , fork , kill , signal , sleep , wait Instead of abort , consider using the STOP statement.
Virtual memory allocation falloc , free , malloc For arrays and pointers, consider using the standard Fortran 95/90 ALLOCATABLE attribute or the ALLOCATE and DEALLOCATE statements.

Table 12-2 describes the 3f routines that provide special functions allowing Compaq Fortran and C language programs to work together.

Table 12-2 3f Library Routines Providing Special Functions
Routine Name Function and Comments
for_rtl_init_ Allows a C main language program to use the Compaq Fortran Run-Time Library environment by initializing the environment, including associated signal handlers; see for_rtl_init_ in Table 12-3
for_rtl_finish_ Allows a C main language program to terminate use of the Compaq Fortran Run-Time Library environment; see for_rtl_finish_ in Table 12-3.
for_get_fpe Returns information on the floating-point exception handling established for the current program unit; see for_get_fpe in Table 12-3. To use for_get_fpe from a C program, you must first call for_rtl_init_ .
for_set_fpe Sets the floating-point exception handling established for the current program unit; see for_set_fpe in Table 12-3. To use for_set_fpe from a C program, you must first call for_rtl_init_ .
getfd Returns the file descriptor associated with a unit number, after the Compaq Fortran Run-Time Library environment has opened the file; see getfd in Table 12-3.
omp_* (TU*X ONLY) Various OpenMP Fortran API run-time routines related to parallel processing; see omp_* in Table 12-3, also Section D.1.
ots* Various Compaq Fortran run-time routines related to parallel processing; see Section D.2.
shcom_connect (TU*X ONLY) Allows multiple processes to access common block data in a shared library (uses memory mapping); see shcom_connect(3f) .

For More Information:


Previous Next Contents Index