Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Call to C_F_Pointer/ISO_C_BINDING

victor_pp
Novice
2,085 Views
I am trying to compile the sample code illustrating how to pass correctly derived types from Fortran to C.
Intel Fortran compiler gives the following error message:

fmain.f90(44): error #6285: There is no matching specific subroutine for this generic subroutine call. [C_F_POINTER]

call c_f_pointer(A%status,status,N)

-------^

compilation aborted for fmain.f90 (code 1)
It compileswithout problemswith Portland compiler.

What is wrong with this sample?
Victor.

0 Kudos
1 Solution
TimP
Honored Contributor III
2,085 Views
According to MR&C, if the third argument to c_f_pointer is present, it must be a rank 1 array, where you gave it a scalar. So the compiler treats your c_f_pointer as a generic, not matching the specific version defined in the standard.
If I change that, it runs through the first iteration of your final loop before crashing (apparently due to the discrepancies in your declaration of status).

View solution in original post

0 Kudos
4 Replies
Arjen_Markus
Honored Contributor II
2,085 Views
My guess is that N in the call to c_f_pointer ought to be an array,
in this case an array of one long.

Regards,

Arjen
0 Kudos
TimP
Honored Contributor III
2,086 Views
According to MR&C, if the third argument to c_f_pointer is present, it must be a rank 1 array, where you gave it a scalar. So the compiler treats your c_f_pointer as a generic, not matching the specific version defined in the standard.
If I change that, it runs through the first iteration of your final loop before crashing (apparently due to the discrepancies in your declaration of status).
0 Kudos
victor_pp
Novice
2,085 Views
Thank you Arjen and Tim! This did the trick.
The output is now the same asproduced withPortland compiler :

C:\Download\FortranStuff\ISO_C_BINDING>fmain

1 10 100

1 1 10

2 2 9

3 3 8

4 4 7

5 5 6

6 6 5

7 7 4

8 8 3

9 9 2

10 10 1


Victor.
[bash]module type_mod 

  use, intrinsic::iso_c_binding 

  type, bind(c) :: type2_t 
     integer(c_int) :: idx, size 
  end type type2_t 

  type, bind(c) :: type3_t 
     integer(c_int) :: idx, size 
  end type type3_t 

  type, bind(c) :: type1_t 
     type(type2_t) :: params 
     type(c_ptr) :: status 
     integer(c_int) :: idx 
  end type type1_t 

end module type_mod 

program test_f_to_c 

  use, intrinsic ::iso_c_binding 
  use type_mod 

  interface 
     subroutine init_data(A,N) bind(c) 
       use, intrinsic:: iso_c_binding 
       use type_mod 
       type(type1_t) :: A 
       integer(c_int), value :: N 
     end subroutine init_data 
  end interface 
  
!  integer, value :: N 
  integer, parameter:: N=10 
  type(type1_t) :: A 
  integer :: i, N1(1) 
  type(type3_t), dimension(:), pointer :: status 
  
  call init_data(A,N) 

  print *, A%idx, A%params%idx, A%params%size
  N1(1)=N 
  call c_f_pointer(A%status,status,N1) 
  do i=1,N 
     print *, i, status(i)%idx, status(i)%size 
  enddo 
      
end program test_f_to_c 

#include  
#include  


typedef struct TYPE3_T { 
    int idx; 
    int size; 
} type3_t; 

typedef struct TYPE2_T { 
    int idx; 
    int size; 
} type2_t; 

typedef struct TYPE1_T { 
  type2_t params; 
  type3_t *status; 
  int idx; 
} type1_t; 


void init_data(type1_t * A, int N) { 
  int i;
  A->idx = 1; 
  A->params.idx = 10; 
  A->params.size = 100; 

  A->status = (type3_t*) malloc(sizeof(type3_t) * N); 
  for (i=0; istatus.idx = i+1; 
    A->status.size = N-i; 
  } 

} 

[/bash]
0 Kudos
Arjen_Markus
Honored Contributor II
2,085 Views
You're welcome - I need to get comfortable with iso_c_binding myself too

Regards,

Arjen
0 Kudos
Reply