Missing Parameters in C Function Called from Fortran

I am working with Fortran 90 code that calls function C. This code is well tested and successfully compiles with the Intel Fortran compiler. I am trying to get it to work with the GNU Fortran compiler. Code F90 calls function C, but does not indicate some parameters. The call is as follows:

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

which apparently works fine with ifort but not gfortran, which fails with an error

 Error: Syntax error in argument list at (1) 

where 1 is a comma after the first empty argument. I can not find any information about what is happening here. Is this specific Intel compiler syntax for passing dummy arguments? If so, can someone point me a link?

+4
source share
1 answer

Ifort actually passes a NULL pointer for unspecified arguments. Compiling and Linking a 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); } 

would you get:

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

This behavior, however, is definitely an extension of the standard. Providing the C functions with an explicit interface in Fortran, you can "emulate" it using any compiler, implementing the Fortran 2003 C-binding functions. You will need to pass the constant C_NULL_PTR for this parameter.

In the Fortran program below, I created an explicit interface for the C function. In this example, Fortran will pass an integer pointer, an arbitrary C pointer, and again an integer pointer.

 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 the explicit name in the bind(c) option, the function name in the C code does not have to contain any magic, trader-dependent underscores. I also changed the types of pointers 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 two components with gfortran (I used 4.7.2) and executing the resulting binary results in:

 P1: 0x400804 P2: (nil) P3: 0x400800 
+2
source

Source: https://habr.com/ru/post/1484878/


All Articles