For Programmers: Free Programming Magazines  


Home > Archive > Fortran > February 2008 > ISO_C_BINDING and generic interfaces









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author ISO_C_BINDING and generic interfaces
Arjen Markus

2008-02-11, 4:30 am

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

2008-02-11, 4:30 am

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

2008-02-11, 4:30 am

On 11 feb, 10:53, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> Arjen Markus wrote:
>
> (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. =A0In the latter case the called routine
> can access the elements of the array from the specified element
> to the end of the array. =A0I 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- 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

2008-02-11, 4:30 am

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)
[color=darkred]
[color=darkred]
[color=darkred]
[color=darkred]
> 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

2008-02-11, 4:30 am

On 11 feb, 11:11, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> 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)
>
>
> But now it gets more interesting. =A0For the scalar case you
> would want to pass a one as the extra argument. =A0Is 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=3D"original name")
real, intent(inout), (dimension(*)|value) :: a
! Pick appropriate keyword
integer, intent(in), value :: b
end subroutine

Regards,

Arjen
fj

2008-02-11, 8:17 am

On 11 f=E9v, 11:20, Arjen Markus <arjen.mar...@wldelft.nl> wrote:
> On 11 feb, 11:11, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
>
>
>
>
>
>
>
>
>
>
> 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=3D"original name")
> real, intent(inout), (dimension(*)|value) :: a


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

2008-02-11, 8:17 am

On 11 feb, 12:04, fj <francois.j...@irsn.fr> wrote:
> On 11 f=E9v, 11:20, Arjen Markus <arjen.mar...@wldelft.nl> wrote:
>
>
>
>
>
>
>
>
>
[color=darkred]
>
>
>
>
>
>
>
>
>
> 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 !- 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

2008-02-11, 8:17 am

On 11 f=E9v, 12:10, Arjen Markus <arjen.mar...@wldelft.nl> wrote:
> On 11 feb, 12:04, fj <francois.j...@irsn.fr> wrote:
>
>
>
>
>
>
>
>
y.[color=darkred]
>
>
>
>
>
>
>
>
>
>
n -[color=darkred]
>
>
> 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.
Steven Correll

2008-02-12, 7:22 pm

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

2008-02-12, 7:22 pm

On 12 f=E9v, 15:57, Steven Correll <steven.corr...@gmail.com> wrote:
> On Feb 11, 12:54 am, Arjen Markus <arjen.mar...@wldelft.nl> wrote:
>
>
>
>
>
>
>
>
>
>
>
> 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=3D...). 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.
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com