Sun Studio 12: Fortran Programming Guide

11.4 Passing Data Arguments by Value

Fortran 95 programs should use the VALUE attribute in dummy arguments when being called from C, and supply an INTERFACE block for C routines that are called from Fortran 95.

Table 11–11 Passing Simple Data Elements Between C and Fortran 95

Fortran 95 calls C  

C calls Fortran 95  


PROGRAM callc
INTERFACE 
 INTEGER FUNCTION crtn(I)
  BIND(C) crtn 
  INTEGER, VALUE, INTENT(IN) :: I 
 END FUNCTION crtn
END INTERFACE 
M = 20 
MM = crtn(M) 
WRITE (*,*) M, MM
END PROGRAM

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

int crtn(int x)
{
  int y;
  printf("%d input \n", x);
  y = x + 1;
  printf("%d returning \n",y);
  return(y);
}

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

Results:
20 input
21 returning
20 21

#include <stdlib.h>
int main(int ac, char *av[]) {
  to_fortran_(12);
}

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

SUBROUTINE to_fortran(i)
  INTEGER, VALUE :: i
  PRINT *, i
END

Note that if the C routine will be called with different data types as an actual argument, you should include a !$PRAGMA IGNORE_TKR I in the interface block to inhibit the compiler from requiring a match in type, kind, and rank between the actual and dummy argument.

With legacy Fortran 77, call by value was available only for simple data, and only by Fortran 77 routines calling C routines. There was no way for a C routine to call a Fortran 77 routine and pass arguments by value. Arrays, character strings, or structures are best passed by reference.

To pass a value to a C routine from a Fortran 77 routine, use the nonstandard Fortran function %VAL(arg) as an argument in the call.

In the following example, the Fortran 77 routine passes x by value and y by reference. The C routine incremented both x and y, but only y is changed.

Fortran calls C  

Fortran routine:


REAL x, y
x = 1.
y = 0.
PRINT *, x,y
CALL value( %VAL(x), y)
PRINT *, x,y
END

C routine:


void value_( float x, float *y)
{
  printf("%f, %f\n",x,*y);
  x = x + 1.;
  *y = *y + 1.;
  printf("%f, %f\n",x,*y);
}

Compiling and running produces output:


1.00000 0.          x and y from Fortran
1.000000, 0.000000  x and y from C
2.000000, 1.000000  new x and y from C
1.00000 1.00000     new x and y from Fortran