Reputation: 1268
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?
Upvotes: 4
Views: 236
Reputation: 3812
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
Upvotes: 2