Fortran and C interoperability

(a.k.a. How to call C from Fortran, or to call Fortran from C?)

To call C functions from a Fortran program or to call Fortran subroutines from a C program usually involves resolving the following issues:
  • case sensitivity (since C is case sensitive but Fortran is not)
  • possible additional trailing underscore ("_") in C function names (the underscore is added by some Fortran compilers)
  • possible additional Fortran libraries that need to be linked to build the executable
  • Fortran subroutines are always "call by reference" while C can be either "call by reference" or "call by value".

    In the followings, specific examples are given for Intel compilers and GNU compilers. If you are using other compilers, some changes may be required.

    If you still encounter problems after following the examples below, please email atshpc@ucla.edu

    Fortran calling C functions

    Example programs:

    Fortran main program, in free format (f-call-c.f):
      program f_call_c
        integer :: i=1, ierr
        double precision :: x=3.14159
        print *, "Fortran calling C, passing"
        print *, "i=",i,"x=",x
        ierr = cfun(i,x)
      end program f_call_c
    
    C function (cfun.c) -- note the trailing underscore in the function name cfun_:
      #include <stdio.h>
      int cfun_(int *ip, double *xp)
      {
        int i = *ip;
        double x = *xp;
        printf("This is in C function...\n");
        printf("i = %d, x = %g\n", i, x);
        return 0;
      }
    

    How to compile

    Using Intel compilers: icc and ifort:

    $ ifort -free -c f-call-c.f
    $ icc -c cfun.c
    $ ifort -o f-call-c-icc f-call-c.o cfun.o
    $ ./f-call-c-icc
    

    Using GNU compilers: gcc and gfortran

    $ gfortran -ffree-form -c f-call-c.f
    $ gcc -c cfun.c
    $ gfortran -o f-call-c-gcc f-call-c.o cfun.o
    $ ./f-call-c-gcc
    

    C calling Fortran suboutines

    Example programs

    C main program (c-call-f.c) -- note the trailing underscore in the function name for_sub_:
      #include <stdio.h>
      void for_sub_(int *, double *, double *, int *);
      int main()
      {
        int i=1, ny=3;
        double x=3.14159;
        double y[]={1.1, 2.2, 3.3};
        printf("C calling Fortran subroutine, passing\n");
        printf("i=%d, x=%g\n", i,x);
        printf("y[]=%g,%g,%g\n",y[0],y[1],y[2]);
        for_sub_(&i, &x, y, &ny);
        return 0;
      }
    
    Fortran suboutine, in free format ( f_sub.f):
      subroutine FOR_SUB(i,x,y,ny)
        implicit none
        integer :: i, ny
        double precision :: x
        double precision :: y(ny)
        print *, "This is in Fortran routine..."
        print *, "i = ", i, ", x = ", x
        print *, "y = ", y(1:ny)
      end subroutine FOR_SUB
    

    How to compile

    Using Intel compilers: icc and ifort

    $ icc -c c-call-f.c
    $ ifort -free -c f_sub.f
    $ icc -o c-call-f-icc  c-call-f.o  f_sub.o -L/u/local/compilers/intel/fce/current/lib -lifcore -limf
    $ ./c-call-f-icc
    

    Using GNU compilers: gcc and gfortran

    $ gcc -c c-call-f.c
    $ gfortran -ffree-form -c f_sub.f
    $ gcc -o c-call-f-gcc  c-call-f.o f_sub.o  -lgfortran
    $ ./c-call-f-gcc