Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

standard conforming or not ?

7 views
Skip to first unread message

fj

unread,
Oct 13, 2009, 8:50:17 AM10/13/09
to
In rare situations, I need to build up two modules strongly connected
together : the module M1 needs pieces of information from M2 and vice
versa. This is forbidden in F95 and, unfortunately, sub-modules are
not available yet with my favorite compilers. As creating a third
module solving the trouble is not always convenient, I use sometimes a
trick consisting in using BIND(C,name="xxx") .

Example :

MODULE M1
USE iso_c_binding,ONLY:c_int
INTERFACE
SUBROUTINE test1(a) BIND(C,name="test1")
IMPORT c_int
INTEGER(c_int) :: a
END SUBROUTINE
END INTERFACE
END MODULE

MODULE M2
USE M1,ONLY : c_int
IMPLICIT NONE
CONTAINS
SUBROUTINE test(a) BIND(C,name="test1")
INTEGER(c_int),INTENT(out) :: a
a=2
END SUBROUTINE
END MODULE

M1 cannot use M2 because M2 already uses M1. But, thanks to BIND(C),
it can use the routine "test" of M2.

When compiling with ifort, g95 or gfortran, I get no message. But the
NAG compiler issues an error :

$ nagfor -c -f2003 test_bind.f90
NAG Fortran Compiler Release 5.2(668)
Error: test_bind.f90: Duplicate binding label 'test1' for external
procedure TEST1 and module procedure TEST of module M2

Is this trick standard conforming or not ?

Reinhold Bader

unread,
Oct 13, 2009, 9:31:31 AM10/13/09
to
Hello,

In clause 16 of the Fortran 2003 standard, the following can be found:

A binding label of an entity of the program is a global identifier and
shall not be the same as the binding label of any other entity of the
program

So your example is not standard conforming (although even the NAG
compiler might accept it if you compile the two modules separately).

However since this rule does not make sense in your context (there is no
technical reason to disallow an interface to resolve to the same name as
an implementation), the rule has, if I recall correctly, been relaxed in
Fortran 2008:

The global identifier of an entity shall not be the same as the global
identifier of any other entity. Furthermore, a binding label shall not
be the same as the global identifier of any other global entity,
ignoring differences in case.

If I understand this correctly (and I'm not sure I do), the interface is
not a *global* entity of the program, and therefore its label is not a
global identifier. And the implementation, since it is a module
procedure, also is not a global entity, though its binding label is.


Regards

Reinhold

fj schrieb:

Richard Maine

unread,
Oct 13, 2009, 11:49:57 AM10/13/09
to
Reinhold Bader <Ba...@lrz.de> wrote:

> In clause 16 of the Fortran 2003 standard, the following can be found:
>
> A binding label of an entity of the program is a global identifier and
> shall not be the same as the binding label of any other entity of the
> program
>
> So your example is not standard conforming (although even the NAG
> compiler might accept it if you compile the two modules separately).
>
> However since this rule does not make sense in your context (there is no
> technical reason to disallow an interface to resolve to the same name as
> an implementation),

I don't believe that is the intended interpretation of those words. In
fact, I'm quite confident of it (unless I misunderstand what you are
saying). As you note, applying the restriction in that kind of way would
make no sense. It would make it pointless to ever specify a binding
label for a procedure.

I think that perhaps the interpretation is that the interface body
specifies a binding label for the same procedure as the implementation -
not a different one. The other alternative is just that the words are
erroneous and should be corrected, perhaps to something like what you
quote from the f2008 draft. If there is any substantial questionon that,
there probably should be an interpretation request to clarify it. (For
all I know, the f200 wording might be the result of such an interp; I
haven't kept up recently).

Fj's code [elided] looks fine to me, albeit tricky. I'm not sure I'd
recommend the trick, but more because of its trickiness than because of
standard conformance. I could imagine maintenance difficulties arising
because the reason for the C binding is unclear; it also artificially
restricts you to things that are C interoperable, which again could come
up as an issue in program maintenance if some new feature is added to
the subroutine.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain

Reinhold Bader

unread,
Oct 13, 2009, 3:49:11 PM10/13/09
to
Richard Maine schrieb:

> Reinhold Bader <Ba...@lrz.de> wrote:
>
>> In clause 16 of the Fortran 2003 standard, the following can be found:
>>
>> A binding label of an entity of the program is a global identifier and
>> shall not be the same as the binding label of any other entity of the
>> program
>>
>> So your example is not standard conforming (although even the NAG
>> compiler might accept it if you compile the two modules separately).
>>
>> However since this rule does not make sense in your context (there is no
>> technical reason to disallow an interface to resolve to the same name as
>> an implementation),
>
> I don't believe that is the intended interpretation of those words. In
> fact, I'm quite confident of it (unless I misunderstand what you are
> saying). As you note, applying the restriction in that kind of way would
> make no sense. It would make it pointless to ever specify a binding
> label for a procedure.


Let me give this another try ...

When writing this I had in mind a different case, once discussed with
NAG's compiler support:

interface
function foo_1() bind(c, name='foo')
import
integer(c_int) :: foo_1
end function
function foo_2() bind(c, name='foo')
import
integer(c_int) :: foo_2
end function
end interface

According to F2003, both foo_1 and foo_2 are external procedures with different
names, and therefore two different (global) entities of the program, and hence the
above rule applies, and the above is non-conforming.

For Fj's example, test1 is an external procedure, but test is not. However, it
has a binding label, and some lines before the above citation we have:
"Program units, common blocks, external procedures, and entities with binding
labels are global entities of a program." This seems to me to imply that Fj's
example is non-conforming under literal application of F2003 rules, since test1
and test have different names and therefore must be different entities.
(One could argue identification by name is superseded by identification by
binding label, but I consider this ambiguous at best).
If test1 is renamed to test, I guess the example conforms (but is still, now
erroneously) rejected by NAG's compiler.


F2008 completely removes the clause on binding labels cited above and replaces
it by a restriction on global identifiers, where specifically an "... external
procedure with no binding label ... is a global identifier."
So in this case, for Fj's example, test1 is not a global identifier
since it has a binding label (and therefore is still a global entity).
test also is not a global identifier while still being a global entity. This
leaves us with the binding label as the sole global identifier and things seem
to be fine.

Note that the new ruling also makes my example above conforming.

I hope I have understood this now. I don't find this particular part of the
standard easy to decipher. One can only hope that F2008 hasn't gone a step
beyond consistency.

Richard Maine

unread,
Oct 13, 2009, 4:40:27 PM10/13/09
to
Reinhold Bader <Ba...@lrz.de> wrote:

> When writing this I had in mind a different case, once discussed with
> NAG's compiler support:
>
> interface
> function foo_1() bind(c, name='foo')
> import
> integer(c_int) :: foo_1
> end function
> function foo_2() bind(c, name='foo')
> import
> integer(c_int) :: foo_2
> end function
> end interface
>
> According to F2003, both foo_1 and foo_2 are external procedures with
> different names, and therefore two different (global) entities of the
> program, and hence the above rule applies, and the above is
> non-conforming.

Hmm. I think I'll abstain for at least a while on that one. It isn't
clear to me that these are different procedures. Looks to me like these
are two interfaces to the same procedure. You keep talking about
interface bodies as being procedures; I don't think that is accurate.
I'm leaning towards saying that is fine, but I at least waffle a little.

> For Fj's example, test1 is an external procedure, but test is not.

Why do you say that test1 is external? Oh. Hmm. I see. I think that's
an error in f2003 now that you mention it. Looks to me like an error in
integration (I didn't catch nearly all of them). I haven't looked at it
in f2008.

In f2003, Note 12.3 says that an interface body cannot be used to
describe the interface of a module procedure "because the interfaces of
such priocedures are already explicit." However, that logic assumes that
the module procedure is accessed via USE. A module procedure with a
binding label can alternatively be acessed via that binding label.
without USE being involved. That is, after all, how one accesses them
from C, which doesn't know anything about the Fortran USE. Thus the
reasoning cited in Note 12.3 falls apart. That looks to me like material
that did not get appropriately modified when the C interop stuff was
added.

I'm going to claim that the (non-normative) Note 12.3 is incorrect in
that a module procedure with a binding label can be acessed via that
binding label, in which case it can be described by an interface body.

> (One could argue identification by name is superseded by identification by
> binding label, but I consider this ambiguous at best).

I agree that can be confusing, but I think it is the intent. This may be
the crux of why we seem to be dsagreeing. I wouldn't describe it quite
that way. It seems to me that your foo_1 and foo_2 above are just local
names used to refer to the procedure identified by the binding label
foo.

And again, an interface body is not a procedure. It describes the
interface of a procedure, but it is not itself a procedure.

Reinhold Bader

unread,
Oct 13, 2009, 5:35:53 PM10/13/09
to
Richard Maine schrieb:
> Reinhold Bader <Ba...@lrz.de> wrote:
>

>
>> For Fj's example, test1 is an external procedure, but test is not.
>
> Why do you say that test1 is external? Oh. Hmm. I see. I think that's
> an error in f2003 now that you mention it. Looks to me like an error in
> integration (I didn't catch nearly all of them). I haven't looked at it
> in f2008.

It is not only in non-normative text. Page 259 lines 31ff:


31 An interface body in a generic or specific interface block specifies the EXTERNAL attribute and an
32 explicit specific interface for an external procedure or a dummy procedure. If the name of the declared
33 procedure is that of a dummy argument in the subprogram containing the interface body, the procedure
34 is a dummy procedure; otherwise, it is an external procedure.

Furthermore,

35 An interface body specifies all of the characteristics of the explicit specific interface or abstract interface.
36 The specification part of an interface body may specify attributes or define values for data entities that
37 do not determine characteristics of the procedure. Such specifications have no effect.

and BIND(C) is among the characteristics. So the implementation must be consistent with what the
interface says (which is why I did not particularly care about the existing differences).

>
>
>> (One could argue identification by name is superseded by identification by
>> binding label, but I consider this ambiguous at best).
>
> I agree that can be confusing, but I think it is the intent. This may be
> the crux of why we seem to be dsagreeing. I wouldn't describe it quite
> that way. It seems to me that your foo_1 and foo_2 above are just local
> names used to refer to the procedure identified by the binding label
> foo.

This surely is what we want, but F2003 apparently fails to provide it. And I am still not
sure F2008 fixes all issues. Need to (try to) recheck this.

>
> And again, an interface body is not a procedure. It describes the
> interface of a procedure, but it is not itself a procedure.
>

Regards
Reinhold

fj

unread,
Oct 14, 2009, 8:22:03 AM10/14/09
to

This last point could be solved if a syntax like BIND
(FORTRAN,name="...") was authorized ... Indeed, I suppose that the
syntax BIND(C,...) was intended to preserve the possibility to bind to
another language than C. So why not FORTRAN ?

Richard Maine

unread,
Oct 14, 2009, 11:21:06 AM10/14/09
to
fj <franco...@irsn.fr> wrote:

> This last point could be solved if a syntax like BIND
> (FORTRAN,name="...") was authorized ... Indeed, I suppose that the
> syntax BIND(C,...) was intended to preserve the possibility to bind to
> another language than C. So why not FORTRAN ?

You misunderstand what BIND(C) means. I don't feel like draging out teh
standard right now to give the citations. It very specifically already
allows for that capability. It is *NOT* specific to binding to a C
compiler. I don't have the exact wording in front of me, but it only
requires something that can "look like" C in terms of interfacing. The
standard specifically mentions the case that a Fortran compiler can be
its own "companion processor" (i.e. target of BIND(C)).

Or the companion procesor could be some other Fortran compiler - perhaps
one with different calling conventions. Ada is also a notable
possibility, since Ada defines a C interop feature. That makes C a
common "meeting ground" for Fortran and Ada.

In fact, that justifies what might otherwise seem a startling
requirement. The standard requires that an f2003 compiler support one or
more companion procesors. It is not an optional feature. It would be a
bit shocking to me if you could not have a standard-conforming Fortran
compiler without also having a C compiler. But the possibility that the
Fortran compiler can count as its own companion processor means that the
requirement doesn't actualy mean what one might otherwise think at
first.

fj

unread,
Oct 14, 2009, 7:28:55 PM10/14/09
to
On 14 oct, 17:21, nos...@see.signature (Richard Maine) wrote:

> fj <francois.j...@irsn.fr> wrote:
> > This last point could be solved if a syntax like BIND
> > (FORTRAN,name="...") was authorized ... Indeed, I suppose that the
> > syntax BIND(C,...) was intended to preserve the possibility to bind to
> > another language than C. So why not FORTRAN ?
>
> You misunderstand what BIND(C) means. I don't feel like draging out teh
> standard right now to give the citations. It very specifically already
> allows for that capability. It is *NOT* specific to binding to a C
> compiler. I don't have the exact wording in front of me, but it only
> requires something that can "look like" C in terms of interfacing. The
> standard specifically mentions the case that a Fortran compiler can be
> its own "companion processor" (i.e. target of BIND(C)).

Sorry but I don't see what I misunderstood ! I always understood that
BIND(C) meant "look like C". For instance, my original question and
the trick I have introduced shows typically a case where the companion
processor is FORTRAN : There is no C part in that example !

But as you mentioned yourself that the trick was artificially
restricted to things that are C interoperable, I have proposed (in
joking a little bit) a FORTRAN extension with BIND(FORTRAN) which
suppresses that restriction and generates an interface which looks
like a FORTRAN external routine !

OK, I agree that such extension is not really useful here ! If I want
something which looks like a FORTRAN external routine, the easiest way
consists in creating really an external procedure ! And this is what I
have done to solve my actual problem : the routine "test" of the
module M2 has been put outside "M2" ... despite my initial wish to
never develop FORTRAN routines outside modules.

But perhaps, in more complex situations, BIND(FORTRAN) could be useful
anyway ?!

> Or the companion procesor could be some other Fortran compiler - perhaps
> one with different calling conventions. Ada is also a notable
> possibility, since Ada defines a C interop feature. That makes C a
> common "meeting ground" for Fortran and Ada.

Or JAVA which has also a C interop feature.

Richard Maine

unread,
Oct 14, 2009, 8:01:01 PM10/14/09
to
fj <franco...@irsn.fr> wrote:

> But as you mentioned yourself that the trick was artificially
> restricted to things that are C interoperable, I have proposed (in
> joking a little bit) a FORTRAN extension with BIND(FORTRAN) which
> suppresses that restriction and generates an interface which looks
> like a FORTRAN external routine !

Oh. I missed the part about omitting the restriction against things that
aren't C interoperable. Even though that was your main point, I still
managed to miss it. Call it failing eyes. Or something. Sorry. :-)

So the only functionality would be to establish a binding name? I don't
think that would fly. You can already effectively rename Fortran
procedures via USE. That doesn't work in your case because of the
circular module USE restriction. In fact, the whole renaming thing in
the example at hand is just a hack to work around that; renaming is not
the primary objective.

I can't see introducing a feature with such a limited use. It wouldn't
solve the module circularity problem in many cases anyway because this
would apply only to procedures. Module circularity problems often
involve things other than procedures. Types are one other example. (I
suppose one could argue for applying it to types as well).

But the whole thing just seems like a hack anyway. Get around USE
circularity by using a feature for renaming?

I think submodules provide a far better approach to this class of
problem. Yes, I know that you commented that submodules aren't yet
available on many current compilers. But adding a feature to a future
version of the Fortran standard isn't going to fix any problem related
to current compilers not supporting something.

0 new messages