[J3] Polymorphic C_LOC actual argument pointer-associated with an interoperable type: conforming?

Damian Rouson damian at sourceryinstitute.org
Tue May 22 17:43:54 EDT 2018


The code below is excerpted from a first attempt at writing a BIND(C) Fortran implementation of the CFI_address function prototype in ISO_Fortran_binding.h.  Two compilers print “T” twice as I had hoped.  A third compiler prints “T” followed by  “F”.  A fourth compiler generates error messages indicating that the FPTR argument in C_F_POINTER and the X argument of C_LOC shall not be polymorphic.  

The third vendor questioned whether a C_LOC argument can be a polymorphic variable that is pointer-associated with an interoperable variable as in the generic_CFI_address FUNCTION below. The Fortran 2018 DIS states the following regarding the C_LOC argument:
"It shall either be a variable with interoperable type and kind type parameters, or be a nonpolymorphic variable with no length type parameters."

From this, I conclude that a polymorphic variable is ok as long as it is interoperable, but I am confused as to whether the phrase “interoperable type” refers to the declared type or the dynamic type.  If it’s the declared type, then the C_LOC argument is non-conforming and I’m just lucky that two vendors gave me what I wanted as an extension.  If it’s the dynamic type, then I think the third and fourth compilers should match the behavior of the first two.

Given that two compilers already give the desired behavior, I hope it would not be a major burden on vendors for me to propose that Fortran 202X include the word “dynamic” between “interoperable” and “type”.  For what it’s worth, my most common use cases for generic programming arise when interfacing Fortran and C and trying to avoid the combinatorial explosion of variable type/kind/rank.  Fortran 2018 a great deal fo the way toward resolving such issues, but I think suspect there are other cases similar to this one above that Fortran 202X might address more fully. 


module ISO_Fortran_binding_module
  use iso_c_binding, only : c_ptr, c_loc, c_f_pointer, c_int
  implicit none

  type, bind(C) :: CFI_cdesc_t
    type(c_ptr) base_addr
  end type


  type(c_ptr) function integer_CFI_address(dv) bind(C)
    type(CFI_cdesc_t), intent(in), target :: dv
    integer(c_int), pointer :: array(:)
    call c_f_pointer(dv%base_addr,array,[1])
    integer_CFI_address = c_loc(array)
  end function

  type(c_ptr) function generic_CFI_address(dv) bind(C)
    type(CFI_cdesc_t), intent(in), target :: dv
    class(*), pointer :: array(:)
    call c_f_pointer(dv%base_addr,array,[1])
    generic_CFI_address = c_loc(array)
  end function

end module

  use iso_c_binding, only : c_loc, c_int, c_associated
  use  ISO_Fortran_binding_module, only : integer_CFI_address, generic_CFI_address, CFI_cdesc_t
  implicit none
  integer(c_int), target :: fortran_array(1)=[99_c_int]
  type(CFI_cdesc_t), target ::array_descriptor
  array_descriptor%base_addr = c_loc(fortran_array)
  print*, c_associated( array_descriptor%base_addr , integer_CFI_address(array_descriptor) )
  print*, c_associated( array_descriptor%base_addr , generic_CFI_address(array_descriptor) )

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.j3-fortran.org/pipermail/j3/attachments/20180522/ccaf8494/attachment-0001.html>

More information about the J3 mailing list