I am trying to solve a problem with automatic interfaces to C
functions. Suppose you
have a C function with a declaration like this:
int xxx( float *y ); /* No further indication of how y is used */
There are (at least) two probable Fortran interfaces possible:
integer function xxx( y ) bind( c, name = "xxx" )
use iso_c_binding
real(c_float), intent(inout) :: y
end function
and:
integer function xxx( y ) bind( c, name = "xxx" )
use iso_c_binding
real(c_float), intent(inout), dimension(*) :: y
end function
My question is: can I define a generic interface to cover both
possibilities, like:
interface xxx
integer function xxx_1( y ) bind( c, name = "xxx" )
use iso_c_binding
real(c_float), intent(inout) :: y
end function
integer function xxx_2( y ) bind( c, name = "xxx" )
use iso_c_binding
real(c_float), intent(inout), dimension(*) :: y
end function
end interface
(The Fortran compiler can then choose the proper version)
The compiler might object to the use of the same C name or is it not
allowed in
the standard?
Regards,
Arjen
> Suppose you
> have a C function with a declaration like this:
> int xxx( float *y ); /* No further indication of how y is used */
> There are (at least) two probable Fortran interfaces possible:
> integer function xxx( y ) bind( c, name = "xxx" )
> use iso_c_binding
> real(c_float), intent(inout) :: y
> end function
> and:
> integer function xxx( y ) bind( c, name = "xxx" )
> use iso_c_binding
> real(c_float), intent(inout), dimension(*) :: y
> end function
> My question is: can I define a generic interface to cover both
> possibilities, like:
(snip)
Interesting question.
This question almost comes up in Fortran without C interoperability.
For an assumed size array one is allowed to call with either an
array or an array element. In the latter case the called routine
can access the elements of the array from the specified element
to the end of the array. I wonder which interface would be
used in the case of an array element.
(Also, note that the called routine will need some way
to know the length of the array.)
-- glen
Sure, I was a trifle too lazy to add an extra argument :).
Regards,
Arjen
(snip on question of calling a C routine with either
a pointer to a scalar (scalar by reference), or an array.)
(I wrote)
>>Interesting question.
>>This question almost comes up in Fortran without C interoperability.
>>For an assumed size array one is allowed to call with either an
>>array or an array element. In the latter case the called routine
>>can access the elements of the array from the specified element
>>to the end of the array. I wonder which interface would be
>>used in the case of an array element.
>>(Also, note that the called routine will need some way
>>to know the length of the array.)
> Sure, I was a trifle too lazy to add an extra argument :).
But now it gets more interesting. For the scalar case you
would want to pass a one as the extra argument. Is there a
way to specify a constant in the interface?
Otherwise, there are two cases, one with and one without
the length argument.
-- glen
Constants would be passed by value ...
I originally came up with the following two routines:
void GetValue( float *value, int index );
void ZeroArray( float *array, int size );
the Fortran 2003 interface could be:
subroutine xxx( a, b) bind(c, name="original name")
real, intent(inout), (dimension(*)|value) :: a
! Pick appropriate keyword
integer, intent(in), value :: b
end subroutine
Regards,
Arjen
Why a choice between dimension(*) and value ? I expected a choice
between dimension(*) and nothing.
About your original question, gfortran complains (compiling error) but
g95 silently agrees. I think that a nice compiler should just issue a
warning in such a case !
Oops, you are right! No VALUE keyword in that case.
Hm, that means it is - at least at the moment - not a
particularly reliable solution.
Regards,
Arjen
A possible solution might consist in imposing additional rules within
C header files. For instance :
void xxx(int *y) -> INTEGER(C_int) :: y
void xxx(int y[]) -> INTEGER(c_int) :: y(*)
I know that this is not convenient with existing header files which do
not follow these rules but this could be OK for new softwares.
The generic interface looks fine to me (the two arguments in question
differ in TKR because they differ in rank.) The F2003 standard imposes
constraints on using a BIND statement, a type declaration statement,
or a PROCEDURE declaration statement to associate the same binding
label with two different entities (C533, C551, C1217) but I can't find
any constraint on using the same binding label with two different
function statements or subroutine statements. Either the wise authors
of the standard anticipated exactly the issue you are confronted with,
or this is a lucky consequence of their not wanting to require the
compiler to perform constraint-checking globally across multiple
program units and modules. :-)
OK : the standard does not require the compiler to issue a message
about names associated to BIND(C,name=...). However I like to see
gfortran reporting that two C names coincide : this is often the
symptom of a mistake I already did several times (via too fast copy/
paste). But here, unfortunately, the two different FORTRAN signatures
really correspond to a unique C signature.
So I think that reporting an error is too strong (I propose to point
out this wrong gfortran behavior to GCC bugzilla) whereas issuing a
simple warning would be very convenient.