Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ISO_C_BINDING and generic interfaces

86 views
Skip to first unread message

Arjen Markus

unread,
Feb 11, 2008, 2:54:04 AM2/11/08
to
Hello,

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

glen herrmannsfeldt

unread,
Feb 11, 2008, 4:53:30 AM2/11/08
to
Arjen Markus wrote:

> 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

Arjen Markus

unread,
Feb 11, 2008, 4:55:01 AM2/11/08
to
> -- glen- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -

Sure, I was a trifle too lazy to add an extra argument :).

Regards,

Arjen

glen herrmannsfeldt

unread,
Feb 11, 2008, 5:11:39 AM2/11/08
to
Arjen Markus wrote:

(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

Arjen Markus

unread,
Feb 11, 2008, 5:20:58 AM2/11/08
to

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

fj

unread,
Feb 11, 2008, 6:04:40 AM2/11/08
to

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 !

Arjen Markus

unread,
Feb 11, 2008, 6:10:41 AM2/11/08
to
> warning in such a case !- Tekst uit oorspronkelijk bericht niet weergeven -

>
> - Tekst uit oorspronkelijk bericht weergeven -

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

fj

unread,
Feb 11, 2008, 7:37:07 AM2/11/08
to

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.

Steven Correll

unread,
Feb 12, 2008, 9:57:21 AM2/12/08
to
On Feb 11, 12:54 am, Arjen Markus <arjen.mar...@wldelft.nl> wrote:
>...Suppose you

> have a C function with a declaration like this:
>
> int xxx( float *y ); /* No further indication of how y is used */
>
> ...

>
> 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 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. :-)

fj

unread,
Feb 12, 2008, 1:42:58 PM2/12/08
to

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.

0 new messages