(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