DIGITAL Fortran 90
User Manual for
DIGITAL UNIX Systems


Previous Contents Index

11.4.9 Example of Passing Complex Data to C Functions

Example 11-9 shows DIGITAL Fortran 90 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 DIGITAL Fortran 90, 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 and user-defined C structures can be passed as arguments if the following conditions are met:

11.4.11 Handling Scalar Pointer Data

When DIGITAL Fortran 90 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, DIGITAL Fortran 90 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 DIGITAL Fortran 90 subprogram, the C program can use pointers to pass numeric data by reference.

Example 11-10 shows a DIGITAL Fortran 90 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 DIGITAL Fortran 90 pointer or target arguments from the example in Example 11-10.

Example 11-11 C Functions Receiving Pointer Arguments

/* C functions Fortran 90 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 DIGITAL Fortran 90 languages handle arrays:

Because of these two factors:

DIGITAL Fortran 90 orders arrays in column-major order. The following DIGITAL Fortran 90 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 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 90 */ 
 
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 DIGITAL Fortran 90 program that calls the C function expshape_ (shown in Example 11-12).

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

! Pass an explicit-shape array from Fortran 90 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 DIGITAL Fortran 90, see Section 11.1.5.

11.4.13 Handling Common Blocks of Data

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

The following examples show how C and DIGITAL Fortran 90 code can access common blocks of data. The C code declares a global structure, calls the f_calc_ DIGITAL Fortran 90 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 function.

11.5 Calling Between Parallel HPF and Non-Parallel HPF Code

When calling between parallel HPF and non-parallel HPF code, the -wsf and -nowsf_main compile-time options are required in certain cases, and prohibited in other cases. For more detailed information, see the DIGITAL High Performance Fortran 90 HPF and PSE Manual.


Chapter 12
DIGITAL Fortran 90 Library Routines

DIGITAL Fortran 90 (DIGITAL Fortran) library routines consist of two groups of routines, commonly referred to by their DIGITAL UNIX reference page section:

When you use the f90 command to compile and link your program, ld automatically searches the object libraries in which the DIGITAL Fortran 90 library routines reside.

When you use ld instead of f90 to link object modules, specify the appropriate DIGITAL Fortran 90 libraries with -l string option. The DIGITAL Fortran 90 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 DIGITAL 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 3f Library Routines

DIGITAL Fortran 90 on DIGITAL UNIX Systems provides a collection of 3f library routines designed to be called from DIGITAL Fortran 90.

The 3f library routines differ from the standard DIGITAL Fortran 90 intrinsic subprograms provided by DIGITAL Fortran 90 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 DIGITAL Fortran 90 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 DIGITAL Fortran 90 errors, such as ERR and IOSTAT. Use these routines to handle DIGITAL UNIX errors.
I/O fgetc , fputc , fseek , ftell , getc , putc Consider using DIGITAL Fortran 90 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 DIGITAL Fortran 90 intrinsic functions INDEX and LEN.
Random numbers drandm , irand , irandm , rand , random , srand Consider using the DIGITAL Fortran 90 intrinsic subroutines RANDOM_NUMBER and RANDOM_SEED.
Return date and time ctime , dtime , etime , fdate , gmtime , idate , itime , ltime , time Consider using the DIGITAL Fortran 90 intrinsic subroutine DATE_AND_TIME or, if you need a subset of the information returned by DATE_AND_TIME, the intrinsic subroutines (DIGITAL 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.
Tape I/O tclose , topen , tread , trewin , tskipf , tstate , twrite None.
Virtual memory allocation falloc , free , malloc For arrays and pointers, consider using the standard Fortran 90 ALLOCATABLE attribute or the ALLOCATE and DEALLOCATE statements.


Previous Next Contents Index