Question

I am working with Fortran 90 code that calls a C function. This code is well tested and compiles successfully with the Intel Fortran compiler. I'm trying to get it to work with the GNU Fortran compiler. The F90 code calls a C function, but it does not specify some of the parameters. The call looks like this:

call c_func_name(1, n, q, , , , p)

which evidently works fine with ifort, but not with gfortran, which fails with the error

Error: Syntax error in argument list at (1)

where 1 is at the comma following the first blank argument. I cannot find any information about what is going on here. Is this an Intel compiler specific syntax for passing dummy arguments? If so, can someone point me to a reference?

Was it helpful?

Solution

Ifort actually passes the NULL pointer for the not specified arguments. Compiling and linking the Fortran program

program test
  implicit none

  call c_func(1, ,3)

end program test

and the corresponding C-function

#include <stdio.h>

void c_func_(void *p1, void *p2, void *p3)
{
  printf("P1: %p\nP2: %p\nP3: %p\n", p1, p2, p3);
}

you would obtain:

P1: 0x4729f4
P2: (nil)
P3: 0x4729f0

This behaviour is, however, definitely an extension to the standard. By giving the C function an explicit interface in Fortran, you can "emulate" it with any compilers, implementing the C-binding features of the Fortran 2003 standard. You would have to pass the C_NULL_PTR constant for the given parameter.

In the Fortran program below, I created an explicit interface for the C-function. In that example Fortran would pass a pointer to an integer, an arbitrary C-pointer and again a pointer to an integer.

program test
  use iso_c_binding
  implicit none

  interface
    subroutine c_func(p1, p2, p3) bind(c, name='c_func')
      import
      integer(c_int) :: p1
      type(c_ptr), value :: p2
      integer(c_int) :: p3
    end subroutine c_func
  end interface

  type(c_ptr) :: cptr

  call c_func(1, C_NULL_PTR, 3)

end program test

Since I used an explicit name in the bind(c) option, the name of the function in the C-code does not need to contain any magic, compiler dependent trailing underscores any more. I also changed the pointer types on the C-side to the corresponding types:

#include <stdio.h>

void c_func(int *p1, void *p2, int *p3)
{
  printf("P1: %p\nP2: %p\nP3: %p\n", p1, p2, p3);
}

Compiling and linking the two componentes with gfortran (I used 4.7.2) and executing the resulting binary results in:

P1: 0x400804
P2: (nil)
P3: 0x400800
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top