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?