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

Malcolm Cohen malcolm at nag-j.co.jp
Tue May 22 22:02:54 EDT 2018

When the standard says “type” with no qualification, unless it is clear from context that it is talking only about one of them, it always means *both* “declared type” and “dynamic type”.


I am adamantly opposed to the proposed insertion of “dynamic” into these requirements (both C_F_POINTER and C_LOC effectively prohibit polymorphic arguments).  Such an insertion would make it harder to detect errors; we should not be doing any such thing.  I really think it makes no sense for CLASS(*) to be permissible but CLASS(T) not to be permissible, since CLASS(*) encompasses CLASS(T) and a whole load more things besides.


Also, C_F_POINTER’s “FPTR” argument is INTENT(OUT) and a POINTER, so

a.	it is not required to be associated or even to have a defined association prior to invocation,
b.	nothing from it’s previous association status is even accessible within C_F_POINTER, let alone relevant to what its result should be,
c.	if there were any doubt, the prohibition of deferred type parameters makes it blindingly obvious.


If you wanted to inherit the declared type from the prior association, that would be a big change!


Given that C has no concept of polymorphism, we would want to be very careful indeed about how we approach this.  Obviously C_F_POINTER is unusable in its current form for polymorphic as well as for deferred length type parameters.


There is also a serious question of length type parameters for C_LOC as well as C_F_POINTER, these have similar issues t to polymorphism (viz “C has no concept”) and one would therefore assume that if one wanted to “do something for polymorphic” one would equally want to “do something for PDTs”, especially since the polymorphic case actually includes PDTs.  Unless of course we want another compile-time-undetectable runtime-random-results-or-crash situation.


There is certainly a use case for permitting “nearly anything” as the argument to C_LOC, but that is merely the first step; one would want to be sure that C_F_POINTER can similarly operate.  Like a MOLD argument to provide the dynamic type and type parameters, for example.  (That’s just a random idea from the top of my head, it needs a lot more thinking about!)


The use case in the message however is unconvincing, since no use of C_F_POINTER is required.  The functions merely need to do

   integer_cfi_address = dv%base_addr

(I realise the pointer arithmetic is omitted, but that likewise not only does not need the requested facility, but using said facility would return the Wrong Answer when the C descriptor describes a noncontiguous object.)


I don’t know why one wouldn’t write CFI_address in C, seeing as how it’s doing stuff with a C descriptor, which is NOT required to be interoperable with Fortran anyway!




..............Malcolm Cohen, NAG Oxford/Tokyo.


From: J3 <j3-bounces at mailman.j3-fortran.org> On Behalf Of Damian Rouson via J3
Sent: Wednesday, May 23, 2018 6:44 AM
To: fortran standards email list for J3 <j3 at mailman.j3-fortran.org>
Cc: Damian Rouson <damian at sourceryinstitute.org>; Daniel Celis Garza <daniel.celisgarza at hmc.ox.ac.uk>
Subject: [J3] Polymorphic C_LOC actual argument pointer-associated with an interoperable type: conforming?




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:

1.	"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) )





The Numerical Algorithms Group Ltd is a company registered in England and Wales with company number 1249803. The registered office is: Wilkinson House, Jordan Hill Road, Oxford OX2 8DR, United Kingdom. Please see our Privacy Notice <https://www.nag.co.uk/content/privacy-notice>  for information on how we process personal data and for details of how to stop or limit communications from us.

This e-mail has been scanned for all viruses and malware, and may have been automatically archived by Mimecast Ltd, an innovator in Software as a Service (SaaS) for business.

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

More information about the J3 mailing list