generic interface and not referred ambiguous symbols

20 views
Skip to first unread message

Tobias Burnus

unread,
Dec 3, 2006, 4:10:15 PM12/3/06
to
Hello,

Assume:

module mod1
interface generic
subroutine foo(a)
real :: a
end subroutine
end interface generic
end module mod1

module mod2
interface generic
subroutine bar(a)
real :: a
end subroutine
end interface generic
end module mod2

program main
use mod1
use mod2
! without using call generic(r)
end program main

To my understanding this is a valid program as long as I don't try to
access "generic".


However, what is about the following case:

module mod1
private modproc
interface generic
module procedure modproc
end interface generic
contains
subroutine modproc()
end subroutine modproc
end module mod1
module mod2
use mod1
interface generic
module procedure modproc
end interface generic
contains
subroutine modproc()
end subroutine modproc
end module mod2

Is this invalid or only invalid as soon as I call generic?

Thanks,

Tobias

Richard Maine

unread,
Dec 3, 2006, 4:31:14 PM12/3/06
to
Tobias Burnus <bur...@net-b.de> wrote:
[modules with conflicting definitions of generic]

> program main
> use mod1
> use mod2
> ! without using call generic(r)
> end program main
>
> To my understanding this is a valid program as long as I don't try to
> access "generic".

Ok, but slightly subtle. Note that it is more than just that you can't
call generic. The name can't appear in the scope at all. For example, if
you added an ONLY specifying generic on either or both of the USE
statements, then it would be invalid.

Mostly, you should realize that this is not a property of generics; it
is a property of USE. You can use two modules that have conflicting
definitions of a name, as long as you don't actually use that name at
all. The name in question doesn't have to be a generic (in either
module).

> However, what is about the following case:
>
> module mod1
> private modproc
> interface generic
> module procedure modproc
> end interface generic
> contains
> subroutine modproc()
> end subroutine modproc
> end module mod1
> module mod2
> use mod1
> interface generic
> module procedure modproc
> end interface generic
> contains
> subroutine modproc()
> end subroutine modproc
> end module mod2
>
> Is this invalid or only invalid as soon as I call generic?

This is invalid. The name generic appears in mod2. See my earlier
explanation. Calling generic has nothing to do with the question
ineither case. It is whether the name generic appears at all in the
scoping unit that USEs the module. It appears here.

The condition that makes your first example ok is basically for allowing
two modules to have conflicting definitions of something as long as that
thing is completely irrelevant to the code USEing the modules.

It is also a feature I wouldn't recommend intentionally using.

Invalid generics are invalid in their definition - it does not depend on
whether they are called. In fact, I almost incorrectly answered saying
that your first example was invalid before I recalled the condition that
allowed it. The only thing that makes it valid is that there is never a
generic defined with the conficting specifics because the lack of use of
the name keeps the USE from bringing the definitions in. That's a bit
subtle in my view. (And it woudln't surprise me if someone else posts
the same wrong answer that I almost did).

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

Tobias Burnus

unread,
Dec 3, 2006, 5:38:01 PM12/3/06
to
Richard Maine wrote:
> Mostly, you should realize that this is not a property of generics; it
> is a property of USE. You can use two modules that have conflicting
> definitions of a name, as long as you don't actually use that name at
> all. The name in question doesn't have to be a generic (in either
> module).

Thanks, your answer was as always very informative!
Now that I know where to look it, I have found it in the standard
(Fortran 2003, Section 11.2.1; F95, Sec 11.3.2):

"Two or more accessible entities, other than generic interfaces or
defined
operators, may have the same identifier only if the identifier is not
used to
refer to an entity in the scoping unit. Generic interfaces and defined
operators are handled as described in section 16.2.3. Except for these
cases,
the local identifier of any entity given accessibility by a USE
statement shall
differ from the local identifiers of all other entities accessible to
the
scoping unit through USE statements and otherwise."

> For example, if you added an ONLY specifying generic on either or both of the USE
> statements, then it would be invalid.

Interestingly, using "use mod1, only: generic" in the first example, no
compiler gives an error or a warning. (I tried ifort, sunf95, NAG f95
and Lahey.)*

For the second invalid case, only ifort gave an error and Lahey a
warning.

This seems to be a darker corner of the Fortran 95+ implementations.

Tobias

* some other compilers already reject the first, valid code.

Steve Lionel

unread,
Dec 4, 2006, 9:55:10 AM12/4/06
to
Tobias Burnus wrote:

> > For example, if you added an ONLY specifying generic on either or both of the USE
> > statements, then it would be invalid.
>
> Interestingly, using "use mod1, only: generic" in the first example, no
> compiler gives an error or a warning. (I tried ifort, sunf95, NAG f95
> and Lahey.)*

When I try this with a current ifort, I get an appropriate diagnostic:

t.f90(19) : Warning: The type/rank/keyword signature for this specific
procedure
matches another specific procedure that shares the same generic-name.
[BAR]
use mod2
------^


Steve Lionel
Developer Products Division
Intel Corporation
Nashua, NH

User communities for Intel Software Development Products
http://softwareforums.intel.com/
Intel Fortran Support
http://developer.intel.com/software/products/support/
My Fortran blog
http://www.intel.com/software/drfortran

Tobias Burnus

unread,
Dec 6, 2006, 2:15:49 PM12/6/06
to
Hi again,

Tobias Burnus wrote:
> > Mostly, you should realize that this is not a property of generics; it
> > is a property of USE. You can use two modules that have conflicting
> > definitions of a name, as long as you don't actually use that name at
> > all. The name in question doesn't have to be a generic (in either
> > module).
>

> (Fortran 2003, Section 11.2.1; F95, Sec 11.3.2):
>
> "Two or more accessible entities, other than generic interfaces or defined
> operators, may have the same identifier only if the identifier is not
> used to refer to an entity in the scoping unit. Generic interfaces and defined
> operators are handled as described in section 16.2.3. Except for these
> cases, the local identifier of any entity given accessibility by a USE
> statement shall differ from the local identifiers of all other entities accessible to
> the scoping unit through USE statements and otherwise."
>
> > For example, if you added an ONLY specifying generic on either or both of the USE
> > statements, then it would be invalid.

I heard from Malcolm Cohen that he disagrees that the first example
("use mod1; use mod2" without "only") is valid. He thinks it is invalid
because of the "Generic interfaces and defined
operators are handled as described in section 16.2.3 [Restrictions on
generic declarations]" clause.

If I understand the standard now correctly [and I'm not good at reading
the fine points of the standard], then the first example is wrong
because "generic" is a generic interface and it would be also wrong if
it were an operator (like .generic.).
If I had only a normal procedure or a global variable etc. in one
module and another one with the same name (and same arguments) in the
second module, then it would be invalid only when the symbol is
referred.
(I actually failed to find the wording in the standard which hints that
already using "only" is enough to count as "referred".)

Is this now correct or do I still miss some essential points?

Tobias

Richard E Maine

unread,
Dec 6, 2006, 3:06:11 PM12/6/06
to
Tobias Burnus <bur...@net-b.de> wrote:

> I heard from Malcolm Cohen that he disagrees that the first example
> ("use mod1; use mod2" without "only") is valid. He thinks it is invalid
> because of the "Generic interfaces and defined
> operators are handled as described in section 16.2.3 [Restrictions on
> generic declarations]" clause.

Well... I'll admit that it is at least a subtle point. And Malcolm is a
bright person whose opinion I respect a lot. On the other hand, I'd want
to be sure that Malcolm was told the reason for arguing that it was
legal. I find the reason easy to overlook - almost did myself. If
someone failed to mention that to him, he might have overlooked it also.

My basis is in 11.2.1, where it says

"Two or more accessible entities, other than generic interfaces or
defined operators, may have the same identifier only if the identifier
is not used to refer to an entity in the scoping unit."

Now it is true that this says "other than generic interfaces...", but
the exact interpretation of that exception is... tricky. I'd probably
say the wording was ambiguous. My interpretation is that the "if" in the
"only if" also applies to generic interfaces. That is, I think a generic
interface is allowed to have the same as another generic interface as
long as the identifier is not used. The exception is that generic
interfaces can sometimes have the same name even if the entity is used.

After all, you certainly can't have one USE access a generic interface
while another use accesses, say, a named constant with the same name, an
dthen expect to be able to refer to that name and have the compiler
figure it out. That would be ambiguous nonsense in at least some cases,
and it isn't touched on by 16.2.3, which is just about multiple
specifics in a generic - not about generics clashing with non-generics.

I think the sentence that I quoted from 11.2.1 is what avoids that. But
if you interpret the "other than" to mean that the sentence says nothing
about generics, then I see a problem.

I'm interpreting that sentence as saying that we have 2 different
generics with that name. That they aren't merged using the rules of
16.2.3 unless "the identifier is used to refer to an entity" in the
scoping unit. I'll admit that this is a very subtle argument. And if
Malcolm worked hard enough at it, he could probably convince me to
change sides.

I will also claim that programmers shouldn't care. Even if it is valid
as I think, don't do that anyway. As a programmer, you don't actually
*HAVE* to do every quirky thing that the language allows. Compiler
writers have a harder job here; they don't get to say "don't do that"
for standard-conforming code.

> (I actually failed to find the wording in the standard which hints that
> already using "only" is enough to count as "referred".)

That one I *DO* understand and I know was intentional. The distinction
is subtle and I don't particularly like it, but I know what it is.

The term "reference" has specific technical meaning in the standard.
There are plenty of ways that an identifier can appear without
constituting a reference. This turns out to be important for lots of
things. For a trivial example

x = 1.0

is not a reference to x. If it were, then you couldn't have that
statement when x was undefined (which would be nonsense, saying that you
couldn't define it unless itwas already defined.) For a variable, a
reference is something that uses the existing value.

The quoted restriction specifically did not intend to be restricted just
to references. If you say x=1.0, it does have to be well defined what x
you are talking about, even though it is not a reference.

The general rule is that English terms that are not given specific
technical meanings in the standard have their "normal English meaning".
I think something in the standard might even say that, although I don't
off-hand see it right now. In any case, it is implied. If one didn't
start with normal English, it would be pretty hard to bootstrap to
anything, since it would be self-referential to say that English words
mean what they mean in English. Of course, well all know that the
"normal English meaning" of something can be ambiguous, but that's a
deeper matter. Yes, I have listened to and participated in discussions
about what the word "is" means in the Fortran standard.

In this particular case, although "referred to" has an awfully simillar
root to "referenced", it isn't the same word and the distinction was
intenional. It would have said "referenced" if that's what it meant. I
don't recall why a more clearly different term such as "appears" wasn't
used; maybe there was a reason. Anyway... by the "normal English
meaning", the name in an ONLY is referring to something - that's what
names do.

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain| experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain

Tobias Burnus

unread,
Dec 6, 2006, 4:53:50 PM12/6/06
to
Thanks for your prompt reply.

Richard E Maine wrote:
> Well... I'll admit that it is at least a subtle point. And Malcolm is a
> bright person whose opinion I respect a lot. On the other hand, I'd want
> to be sure that Malcolm was told the reason for arguing that it was
> legal. I find the reason easy to overlook - almost did myself. If
> someone failed to mention that to him, he might have overlooked it also.

Well, I pointed him to this comp.lang.fortran thread thus he should
have read your reply.


> I will also claim that programmers shouldn't care. Even if it is valid
> as I think, don't do that anyway. As a programmer, you don't actually
> *HAVE* to do every quirky thing that the language allows. Compiler
> writers have a harder job here; they don't get to say "don't do that"
> for standard-conforming code.

Besides, even if it is valid, if cou cannot refer it, it is of no use.

The actual reason why I asked this is, however, indeed about compiler
writing. It came up while fixing a rejectes-valid-code issue in
gfortran (the initial issue was unambiguous). And Malcolm Cohn became
involved because NAG f95 (one of my test compilers to quickly check if
something is valid Fortran) didn't reject some related, invalid code.


> > (I actually failed to find the wording in the standard which hints that
> > already using "only" is enough to count as "referred".)
>
> That one I *DO* understand and I know was intentional. The distinction

> is subtle and I don't particularly like it, but I know what it is. [...]


> Of course, well all know that the
> "normal English meaning" of something can be ambiguous, but that's a
> deeper matter. Yes, I have listened to and participated in discussions
> about what the word "is" means in the Fortran standard.

Thanks. It is reassuring that it is not only me who is struggling about
the finer points of the standard. By the way, in general I find the
standard quite readable and a nice reference. Especially, given that
every word had to be weighted carefully. Thanks to all Fortran standard
editors, critcal readers, feature proposers for the nicely written
standard and the great programming language! (And to all compiler
writers without it would be a lifeless stack of paper.)

Tobias

PS: Has something exist to be? Or does it turns into existance by
being? To be or not to be this is the question. ;-)

Dick Hendrickson

unread,
Dec 6, 2006, 5:13:59 PM12/6/06
to
Tobias Burnus wrote:
> Thanks for your prompt reply.
>
> Richard E Maine wrote:
>> Well... I'll admit that it is at least a subtle point. And Malcolm is a
>> bright person whose opinion I respect a lot. On the other hand, I'd want
>> to be sure that Malcolm was told the reason for arguing that it was
>> legal. I find the reason easy to overlook - almost did myself. If
>> someone failed to mention that to him, he might have overlooked it also.
>
> Well, I pointed him to this comp.lang.fortran thread thus he should
> have read your reply.
>
>
>> I will also claim that programmers shouldn't care. Even if it is valid
>> as I think, don't do that anyway. As a programmer, you don't actually
>> *HAVE* to do every quirky thing that the language allows. Compiler
>> writers have a harder job here; they don't get to say "don't do that"
>> for standard-conforming code.
>
> Besides, even if it is valid, if cou cannot refer it, it is of no use.
>

This is a longish thread, and my newsreader declines to find the start
of it, so I may have missed something here. But, I think the "reason"
for allowing two modules to have different objects with the same name
is to allow modules to grow harmlessly. If you USE two modules that are
being maintained/developed by two different people, they can each add
new stuff with somewhat less worry about name conflicts. So long as you
don't refer to the new stuff, it's OK for the two USE statements to
silently bring it in.

Dick Hendrickson

Jan Vorbrüggen

unread,
Dec 7, 2006, 7:22:37 AM12/7/06
to
> I think the sentence that I quoted from 11.2.1 is what avoids that. But
> if you interpret the "other than" to mean that the sentence says nothing
> about generics, then I see a problem.

That's definitely how _I_ read that passage in question. But who am I to tell
you how a passage in English should be interpreted? If it were in German, that
would be another matter 8-).

From this interpretation, it also follows that for generic interfaces and
defined operators, the merging of section 16.2.3 is always triggered - at
least it seems so to me.

> I will also claim that programmers shouldn't care. Even if it is valid
> as I think, don't do that anyway. As a programmer, you don't actually
> *HAVE* to do every quirky thing that the language allows. Compiler
> writers have a harder job here; they don't get to say "don't do that"
> for standard-conforming code.

Nicely put, and quite agreed.

Jan

Reply all
Reply to author
Forward
0 new messages