(j3.2006) Ian Harvey complains about F08/0142 (can't have a submodule of module with no separate module procedures)

Lionel, Steve steve.lionel
Mon Jan 4 10:12:14 EST 2016


I am just passing this on, though I did reply in the newsgroup that several
implementers (including us) said that the overhead of not having the
constraint was considerable.

 

Steve Lionel

Intel Developer Support

Merrimack, NH

-------- Forwarded Message --------
Subject: Re: BIND(C) module procedures in submodules
Date: Thu, 31 Dec 2015 09:08:38 +1100
From: Ian Harvey <ian_harvey at bigpond.com>
Organization: A noiseless patient Spider
Newsgroups: comp.lang.fortran
References: <msjens$nqe$1 at dont-email.me> <msk7su$mln$1 at dont-email.me>
<mska2p$dm$1 at dont-email.me>
<ed57f13b-ab79-45e4-80a0-e8f35def025f at googlegroups.com>
<1madn4p.1e9w04vwzdvpaN%nospam at see.signature>
<cfe10c7c-9a51-4591-9d07-2105c12b3b44 at googlegroups.com>
<msltcg$cpl$1 at dont-email.me>

Intepretation F08/0142, currently before J3, deals in part with the 
topic of this thread (it was the inspiration for the original post). In 
its current form I don't think the draft response to that interpretation 
is accurate, and I think it potentially introduces a pointless annoyance 
into the language.

The body text of that interpretation states:

If a module declares no separate module procedure, it cannot
have a useful submodule as such a submodule has nothing to
provide. Its module procedures and variables cannot be
referenced by any program.

The example in the original post of this thread, expanded to a more 
useful example in the quoted reply below, of a module procedure in a 
submodule with a binding label, contradicts the assertions in both 
sentences of that paragraph. The submodule has something to provide - a 
procedure in that submodule with a binding label can be referenced.

(It is perhaps debatable how useful such an arrangement is, but I don't 
think you can argue it is not useful at all.)

The response of that interpretation is to ban, by constraint, submodule 
extension of a module that has no declarations of separate module 
procedures.

Having declarations of a separate module procedure is a property of the 
module, so a simple work around, if the interpretation was passed, would 
be to add a single such declaration to the module that is otherwise 
never referenced (I think the definition could also go after the 
CONTAINS statement in the module). I think this is then an example of 
pointless code added to work around a pointless restriction.

MODULE m
IMPLICIT NONE
INTERFACE
MODULE SUBROUTINE pointless ; END SUBROUTINE pointless
END INTERFACE
INTEGER, PRIVATE :: x
CONTAINS
MODULE SUBROUTINE pointless ; END SUBROUTINE pointless
END MODULE m

SUBMODULE (m) sm
IMPLICIT NONE
CONTAINS
SUBROUTINE set_it(arg) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT
INTEGER(C_INT), INTENT(IN), VALUE :: arg
x = arg
END SUBROUTINE set_it
FUNCTION get_it() BIND(C)
USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT
INTEGER(C_INT) :: get_it
get_it = x
END FUNCTION get_it
END SUBMODULE sm

~~~

void set_it(int arg);
int get_it();

int main()
{
set_it(10);
printf("%d\n", get_it());
return 0;
}

The rationale for the restriction in the draft interpretation - 
"Permitting such extension would require the implementation to
export the private details of a module merely for the purpose of
compiling a useless submodule" - is questionable, as implementations 
often have to export many of the private details of a module anyway, for 
reasons unrelated to submodules.

This is far from being a critical issue for the language, but if someone 
from J3 is listening I would appreciate it if my comments could be 
forwarded for consideration.


(The interp is in the current straw ballot 11 - see 
http://mailman.j3-fortran.org/pipermail/j3/2015-December/008768.html )

On 2015-09-08 3:59 PM, Ian Harvey wrote:
> On 2015-09-08 1:23 PM, FortranFan wrote:
>> On Monday, September 7, 2015 at 2:55:20 PM UTC-4, Richard Maine wrote:
>>> ..
>>>
>>> You are missing the fact that C code does not access module procedures
>>> (or anything) via USE statements. ..
>>>
>>> The misunderstanding was the notion that PRIVATE was somehow related to
>>> security in keeping things outside the module from being able to access
>>> an entity. But basically, it isn't. PRIVATE is related only to namespace
>>> control.
>>>
>>> ..
>>
>> Undoubtedly my understanding of a lot of things concerning Fortran is
>> rather limited, but the aspect about PRIVATE attribute in a module and
>> its irrelevance with something external accessing a module entity is,
>> thankfully, not among them.
>>
>> When a C code (or external Fortran or any other code) accesses a
>> module procedure and when the USE statement is not coming into play,
>> where do  interfaces come in to the equation?  The consumer is
>> providing its own interface in such a scenario.
>
> The equivalent of the interface of the procedure is described to the the
> C code via the function prototype in the C code for the procedure.
>
>
>> The point I was asking more clarification on was about "providing
>> bolt-on interoperable C interfaces to a module" via a submodule.  How
>> is this possible?
>
> For example, consider a pretend module that has a public type with
> private components, and some public and private procedures that work
> with that type.
>
> MODULE m
>    IMPLICIT NONE
>    PRIVATE
>    PUBLIC :: FortranProc
>    INTEGER, PUBLIC :: rk = KIND(1.0)  ! or whatever
>
>    TYPE, PUBLIC :: FortranType
>      REAL(rk), ALLOCATABLE, PRIVATE :: comp(:)
>    END TYPE :: FortranType
>
>    INTERFACE FortranType
>      MODULE PROCEDURE constructor
>    END INTERFACE FortranType
> CONTAINS
>    FUNCTION constructor(...)
>      TYPE(FortranType) :: constructor
>      constructor%comp = whatever...
>    END FUNCTION constructor
>
>    SUBROUTINE FortranProc(object, result)
>      TYPE(FortranType), INTENT(IN) :: object
>      REAL(rk), INTENT(OUT) :: result
>      ! Perhaps some Fortran encapsulation specific stuff...
>      IF (.NOT. ALLOCATED(object%comp)) THEN
>        ERROR STOP 'Operation prior to construction.'
>      END IF
>      ! Now get into the calculation...
>      CALL private_implementation(object%comp, result)
>    END SUBROUTINE FortranProc
>
>    ! Here is where the real action happens.  But this is not
>    ! intended to be directly called from Fortran client code,
>    ! so it is private.
>    SUBROUTINE private_implementation(array, result)
>      REAL(rk), INTENT(IN) :: array(:)
>      REAL(rk), INTENT(OUT) :: result
>      ! Some example calculation
>      result = SUM(array)
>    END SUBROUTINE private_implementation
> END MODULE m
>
>
> Nothing in the above is interoperable - you would have to write a set of
> wrapper procedures (which could perhaps be in another module) that work
> through the public interfaces in order for it to be called by C code.
>
> And perhaps that's ok.  Or, perhaps, the encapsulation provided by the
> FortranType type and the public procedures doesn't add anything bar
> overhead to C client code that wants to access the same function,
> perhaps because the C or C++ code will have its own encapsulation.  With
> what's been discussed in this thread, without touching the module source
> someone could now write a submodule that interacted with the private
> procedures of the module directly (because a submodule is
> part of the module, from the point of view of accessibility):
>
> SUBMODULE (m) c_interfaces
>    IMPLICIT NONE
> CONTAINS
>    SUBROUTINE CProc(size, array, result) BIND(C,NAME='CProc')
>      USE, INTRINSIC :: ISO_C_BINDING, ONLY:  &
>          C_INT, C_FLOAT
>      INTEGER(C_INT), VALUE :: size
>      REAL(C_FLOAT), INTENT(IN) :: array(size)
>      REAL(C_FLOAT), INTENT(OUT) :: result
>
>      ! Here do some C encapsulation specific stuff, then
>      ! invoke the private module procedure to do the real
>      ! work.
>      !
>      ! If objects of type FortranType were floating around,
>      ! we could also access their private components and
>      ! bindings.
>      IF (C_FLOAT == rk) THEN
>        CALL private_implementation(array, result)
>      ELSE
>        BLOCK
>          REAL(rk) :: tmp_array(size)
>          REAL(rk) :: tmp_result
>          tmp = array
>          CALL private_implementation(tmp, tmp_result)
>          result = tmp_result
>        END BLOCK
>      END IF
>    END SUBROUTINE CProc
> END SUBMODULE c_interfaces
>
>
> void CProc(int size, float *array, float *result);
>
> int main()
> {
>     float *array, result;
>     int i, size;
>
>     size = 10;
>     array = malloc(size * sizeof(float));
>     for (i = 0; i < size(); ++ i) {
>       array[i] = i;
>     }
>     CProc(size, array, &result);
>     prinff("%f\n", result);
>     free(array);
>     return 0;
> }
>
>
> For Fortran only code, you can simply omit compiling and linking the
> submodule.
>
> I have no opinion whether this is good/bad/useful/useless, just
> observing it as a possibility.  It could perhaps be a more interesting
> possibility if, as an extension, a particular Fortran compiler offered
> other languages through the BIND(...) mechanism than just C.  When using
> Fortran processors that didn't support that particular extension, then
> don't compile the relevant submodule.




 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mailman.j3-fortran.org/pipermail/j3/attachments/20160104/21d8c7cd/attachment-0001.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 6616 bytes
Desc: not available
Url : http://mailman.j3-fortran.org/pipermail/j3/attachments/20160104/21d8c7cd/attachment-0001.bin 



More information about the J3 mailing list