Fortran POINTER passed to C by ISO_C_BINDING with INTENT(IN)

Viewed 101

Reading a code, I somehow encountered a rather strange grammar on iso_c_binding, and its minimal view is like below.

(Fortran part)

program testF
  use iso_c_binding
  implicit none
  interface
    subroutine get_value_array(arr, num) bind(C)
      use iso_c_binding
      implicit none
(*)   integer(C_INT), dimension(:), pointer, intent(in) :: arr
      integer(C_INT), value, intent(in)                 :: num
    end subroutine
  end interface

  integer(C_INT),dimension(:),pointer :: array
  integer(C_INT) :: n

  n = 7
  allocate(array(n))

  call get_value_array (array, n)

  print *, 'array'
  print *, array

end program

(C++ part)

#include <iostream>

extern "C" void get_value_array(int **in, int num) {
  int i;
  for (i = 0; i < num; i++) {
    (*in)[i] = i+1;
  }
}

After compiling with commands like below,

icc -c testC.cpp
ifort -lstdc++ -o test testF.f90 testC.o
rm *.o

The code actually works and shows the desired output.

 array
           1           2           3           4           5           6
           7

My question is all about the line I marked with (*) at the Fortran part of the code. To learn iso_c_binding stuff, I've searched pretty tones of webpages, stackoverflow literatures, and so on. However, I've never seen that kind of statement where integer(C_INT) + dimension(:) + pointer appear in one line. Acoording to the code, it should mean 'A pointer to int * '.

But you know, in iso_c_binding context, integer(C_INT) alone means int * in C++ perspective, while integer, dimension(:), pointer means 'a pointer to an integer array' in Fortran perspective. Now that they are mixed in one line, it is really confusing. Can anybody clarify how come they get to mean 'A pointer to int * '?

One more, in (*) I only wrote intent(in). In my experience, if I write only intent(in) where intent(inout) is needed, I fail to compile it with following error

error #6780: A dummy argument with the INTENT(IN) attribute shall not be defined nor become undefined.

But I get no error with this example, and I get desired intent(inout) like behavior. Is this some kind of magic with iso_c_binding where intent restrictions are relieved a little bit, or is it just an undefined behavior where I luckily get the desired functionality?

0 Answers
Related