ISO_C_BINDING and generic interfaces - Fortran

This is a discussion on ISO_C_BINDING and generic interfaces - Fortran ; 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 */ ...

+ Reply to Thread
Results 1 to 10 of 10

ISO_C_BINDING and generic interfaces

  1. Default ISO_C_BINDING and generic interfaces

    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

  2. Default Re: ISO_C_BINDING and generic interfaces

    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


  3. Default Re: ISO_C_BINDING and generic interfaces

    On 11 feb, 10:53, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
    > 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- 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

  4. Default Re: ISO_C_BINDING and generic interfaces

    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


  5. Default Re: ISO_C_BINDING and generic interfaces

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

  6. Default Re: ISO_C_BINDING and generic interfaces

    On 11 fév, 11:20, Arjen Markus <arjen.mar...@wldelft.nl> wrote:
    > 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)

    >
    > > >>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


    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 !

  7. Default Re: ISO_C_BINDING and generic interfaces

    On 11 feb, 12:04, fj <francois.j...@irsn.fr> wrote:
    > On 11 fév, 11:20, Arjen Markus <arjen.mar...@wldelft.nl> wrote:
    >
    >
    >
    >
    >
    > > 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)

    >
    > > > >>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

    >
    > 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

  8. Default Re: ISO_C_BINDING and generic interfaces

    On 11 fév, 12:10, Arjen Markus <arjen.mar...@wldelft.nl> wrote:
    > On 11 feb, 12:04, fj <francois.j...@irsn.fr> wrote:
    >
    >
    >
    > > On 11 fév, 11:20, Arjen Markus <arjen.mar...@wldelft.nl> wrote:

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

    >
    > > > > >>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

    >
    > > 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


    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.

  9. Default Re: ISO_C_BINDING and generic interfaces

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

  10. Default Re: ISO_C_BINDING and generic interfaces

    On 12 fév, 15:57, Steven Correll <steven.corr...@gmail.com> wrote:
    > 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. :-)


    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.

+ Reply to Thread