Sun Studio 12: Fortran Programming Guide

11.3.7 Pointers

A FORTRAN 77 (Cray) pointer can be passed to a C routine as a pointer to a pointer because the Fortran routine passes arguments by reference.

Table 11–10 Passing a FORTRAN 77 (Cray) POINTER

Fortran calls C  

C calls Fortran  


REAL X
POINTER (P2X, X)
EXTERNAL PASS
P2X = MALLOC(4)
X = 0.
CALL PASS(P2X)
...

------------------------------

void pass_(p)
> float **p;
{
  **p = 100.1;
}

extern void fpass_( float** );
...
float *p2x;
...
 fpass_(&p2x) ;
...

------------------------------

SUBROUTINE FPASS (P2X)
  REAL X
  POINTER (P2X, X)
  X = 0.
  ...

C pointers are compatible with Fortran 95 scalar pointers, but not array pointers.

Fortran 95 calls C with a scalar pointer  

Fortran 95 routine:


INTERFACE
  SUBROUTINE PASS(P)
   REAL, POINTER :: P
  END SUBROUTINE
END INTERFACE

 REAL, POINTER :: P2X
 ALLOCATE (P2X)
 P2X = 0
 CALL PASS(P2X)
 PRINT*, P2X
END

C routine:


void pass_(p);
float **p;
{
  **p = 100.1;
}

 

The major difference between Cray and Fortran 95 pointers is that the target of a Cray pointer is always named. In many contexts, declaring a Fortran 95 pointer automatically identifies its target. Also, an explicit INTERFACE block is required for the called C routine.

To pass a Fortran 95 pointer to an array or array section requires a specific INTERFACE block, as in this example:


Fortran 95 routine:
INTERFACE
  SUBROUTINE S(P)
    integer P(*)
  END SUBROUTINE S
END INTERFACE
integer, target:: A(0:9)
integer, pointer :: P(:)
P => A(0:9:2) !! pointer selects every other element of A
call S(P)
...

C routine:
void s_(int p[])
{
   /* change middle element */
   p[2] = 444;
}

Note that since the C routine S is not a Fortran 95 routine, you cannot define it to be assumed shape (integer P(:)) in the interface block. If the C routine needs to know the actual size of the array it must be passed as an argument to the C routine.

Again, keep in mind that subscripting between C and Fortran differs in that C arrays start at subscript 0.