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

Passing module procedures to external procedures -- type issues

6 views
Skip to first unread message

Rich Townsend

unread,
Sep 19, 2008, 9:52:32 PM9/19/08
to
Hi all --

Consider the following module:

---CUT---
module foo

implicit none

contains

subroutine main_sub ()

call internal_sub()

contains

subroutine internal_sub()

call QAG(other_sub)

end subroutine internal_sub

end subroutine main_sub

subroutine other_sub ()

end subroutine other_sub

end module foo
---CUT---

(FYI, this is a cut-down version of a more extended code; the external
subroutine QAG, for which an explicit interface is *not* defined, is part of
QUADPACK).

This compiles fine with Intel Fortran (Linux), but on gfortran 4.3.1, I get the
following error:

foo.f90:15.24:

call QAG(other_sub)
1
Error: Symbol 'other_sub' at (1) has no IMPLICIT type

I don't really understand what this error message means; surely, the other_sub
name uniquely identifies a subroutine throughout the whole module? Is my code
standard conforming or not?

Many thanks,

Rich

glen herrmannsfeldt

unread,
Sep 20, 2008, 1:15:06 AM9/20/08
to
Rich Townsend wrote:


> module foo
> implicit none
> contains

> subroutine main_sub
> call internal_sub()
> contains

> subroutine internal_sub()
> call QAG(other_sub)
> end subroutine internal_sub
> end subroutine main_sub

> subroutine other_sub ()
> end subroutine other_sub

> end module foo

No error from g95, either.

> This compiles fine with Intel Fortran (Linux), but on gfortran 4.3.1, I
> get the following error:

> Error: Symbol 'other_sub' at (1) has no IMPLICIT type

Would it be happier with an EXTERNAL statement
for other_sub?

> I don't really understand what this error message means; surely, the
> other_sub name uniquely identifies a subroutine throughout the whole
> module? Is my code standard conforming or not?

Some languages have rules that names have to be defined
before they are used. I believe Fortran doesn't, but
you can imagine with a large number of statements in those
subroutines that the compiler wouldn't find out for a
long time that other_sub is the name of a subroutine.

-- glen

robert....@sun.com

unread,
Sep 20, 2008, 1:06:05 AM9/20/08
to

It is not standard conforming code. As Glen Hermannsfeldt
suggests, you need to either provide an explicit interface
for other_sub or declare it in an EXTERNAL statement. My
guess is that Intel Fortran will report the error to you
if you use the right compiler option.

Bob Corbett

Message has been deleted

robert....@sun.com

unread,
Sep 20, 2008, 1:16:55 AM9/20/08
to

BTW, your code would be standard-conforming if you
removed the IMPLICIT NONE statement, but it might not
do what you expect.

Bob Corbett

Richard Maine

unread,
Sep 20, 2008, 2:25:34 AM9/20/08
to
<robert....@sun.com> wrote:

> On Sep 19, 6:52 pm, Rich Townsend <r...@barVOIDtol.udel.edu> wrote:

> > module foo
> >
> > implicit none
> >
> > contains
> >
> > subroutine main_sub ()
> >
> > call internal_sub()
> >
> > contains
> >
> > subroutine internal_sub()
> >
> > call QAG(other_sub)
> >
> > end subroutine internal_sub
> >
> > end subroutine main_sub
> >
> > subroutine other_sub ()
> >
> > end subroutine other_sub
> >
> > end module foo
> > ---CUT---

> > Is my code standard conforming or not?


>
> It is not standard conforming code. As Glen Hermannsfeldt
> suggests, you need to either provide an explicit interface
> for other_sub or declare it in an EXTERNAL statement. My
> guess is that Intel Fortran will report the error to you
> if you use the right compiler option.

Either Bob's missing something or I am. From what I can see, the code is
fine as is, but would be erroneous if an EXTERNAL statement or interface
body were added. Did you miss the fact that other_sub is not external,
but is instead a module procedure in the same module.

Ok, I take it back. Adding an EXTERNAL statement would not make the code
nonstandard, but it would make it mean something different from the
"obvious". That would mean that the other_sub passed to QAG would not be
the module procedure, but would instead be some external procedure of
the same name (assuming such an external procedure existed).

Now within QAG, there better be something to declare its dummy argument
to hav ethe EXTERNAL attribute, but that's a different matter (and an
unfortunately confusing one - for "hysterical" reasons the EXTERNAL
attribute for a dummy procedure just means that it is a procedure and
has nothing to do with it being external).

Although the code is fine as is (I think), you might be able to give the
compiler a helpful hint by declaring something about other_sub before
its use. About the only such thing you can validly declare is the public
or private attribute. I usually tend to do so for module procedures.
Well, for a start I have to do it for public ones because I make the
default accessibility private. I often do it for private ones as well,
partly in order to make the compiler's job a little easier. The public
or private statement at least tells the compiler that, whatever
other_sub is (which can't be determined until the compiler sees the
procedure), it is at least something from the module scope instead of
something local to internal_sub.

Also, moving the code for other_sub before that of main_sub might help.
It isn't required, and I can see stylistic objections in some cases, but
it might make the compiler's job easier.

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

paul.rich...@gmail.com

unread,
Sep 21, 2008, 3:39:50 PM9/21/08
to
Tobias Burnus posted this as PR35597 and I just confirmed it.

Thanks for the report.... maybe next time in Bugzilla? :-)

Cheers

Paul

steve...@gmail.com

unread,
Sep 21, 2008, 7:11:53 PM9/21/08
to
On Sep 21, 9:39 pm, paul.richard.tho...@gmail.com wrote:
> Tobias Burnus posted this as PR35597 and I just confirmed it.

Actually, http://gcc.gnu.org/PR37597

Note the 37xxx. The number of reported bugs (including enhancement,
and for all of gcc) is close to 8000 per year ;-)

Gr.
Steven

Rich Townsend

unread,
Sep 21, 2008, 11:02:21 PM9/21/08
to

Thanks for the as-ever-insightful remarks, Richard. Can I clarify that I've
understood the overall thrust of your comments: the code is standard-conforming
as is; but as a temporary work-around that *might* help a confused compiler, I
should find some way of letting the compiler 'realize' that other_sub is a
module procedure?

cheers,

Rich

Rich Townsend

unread,
Sep 21, 2008, 11:03:22 PM9/21/08
to
paul.rich...@gmail.com wrote:
> Tobias Burnus posted this as PR35597 and I just confirmed it.
>
> Thanks for the report.... maybe next time in Bugzilla? :-)
>

But of course ;)

(In fact, I wasn't sure whether the problem was with my code, or with gfortran.
Had I been sure of a bug in the compiler, I would have gone to bugzilla -- promise!)

Richard Maine

unread,
Sep 21, 2008, 11:20:26 PM9/21/08
to
Rich Townsend <rh...@barVOIDtol.udel.edu> wrote:

> Can I clarify that I've understood the overall thrust of your comments:
> the code is standard-conforming as is; but as a temporary work-around that
> *might* help a confused compiler, I should find some way of letting the
> compiler 'realize' that other_sub is a module procedure?

Yes. Anyway, that's how I see it. I haven't heard from Bob, who has
certainly been known to see subtle points that I missed. But I think he
probably just overlooked what was going on in this case. If he comes
back with a refutation, I'll listen.

This also brings back recollections of a debate I heard of from before I
was on the committee. I wasn't there at the time, so my data is all
second hand, but if I understood correctly, I believe this was exactly
one of things that was the subject of some debate in the development of
f90. Some people thought that the standard should require that the code
give compilers a hint about things like this so that the compiler wasn't
required to look ahead for it. Others thought that the compilers could
manage that and there was no need for what they viewed as a superflous
restriction in the standard.

I even recall a particular name having been mentioned as someone who
vehemently opposed requiring compilers to figure out such forward
references. She evidently lost the argument. I'll not repeat the name
(except insomuch as the gender narrows it down a bit; there have been
quite a few females on the committee, but they were still enough of a
minority that it narrows it down considerably.)

glen herrmannsfeldt

unread,
Sep 22, 2008, 7:09:26 PM9/22/08
to
Rich Townsend wrote:


> module foo
> implicit none
> contains
> subroutine main_sub ()
> call internal_sub()
> contains
> subroutine internal_sub()
call QAG(other_sub)
> end subroutine internal_sub
> end subroutine main_sub
> subroutine other_sub ()
> end subroutine other_sub
> end module foo

(snip)

> call QAG(other_sub)
> 1
> Error: Symbol 'other_sub' at (1) has no IMPLICIT type

> I don't really understand what this error message means; surely, the
> other_sub name uniquely identifies a subroutine throughout the whole
> module? Is my code standard conforming or not?

Getting back to this, what does it do without the IMPLICIT NONE
statement?

Is it that the compiler figures the code is legal, but
is giving the message due to no type declaration for other_sub?

For an additional complication, what if other_sub were
a function, instead? (other_func, maybe). Should it
have its return type declared in internal_sub?

-- glen

glen herrmannsfeldt

unread,
Sep 23, 2008, 12:47:29 AM9/23/08
to
Richard Maine wrote:
(snip)

> I even recall a particular name having been mentioned as someone who
> vehemently opposed requiring compilers to figure out such forward
> references. She evidently lost the argument. I'll not repeat the name
> (except insomuch as the gender narrows it down a bit; there have been
> quite a few females on the committee, but they were still enough of a
> minority that it narrows it down considerably.)

In the case where a compiler might have to go a few lines
down to find out the needed information, it isn't so bad.
(Often true for Fortran declaration statements.)

In this case, if each subroutine contained thousands
of lines it could be a long way down. Not good at all
if you want to write a one pass compiler.

In the case of IMPLICIT NONE, is this an implicit
declaration of other_sub?

-- glen

Richard Maine

unread,
Sep 23, 2008, 1:47:00 AM9/23/08
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> ...Not good at all if you want to write a one pass compiler.

Nobody does one-pass Fortran compilers any more. Consequently, arguments
about how something won't work well for one-pass compilers carry little
weight in committee. That's not just speculation. I've seen people
mention issues of one-pass compilers, and I've seen the reception that
such mentions get.

> In the case of IMPLICIT NONE, is this an implicit
> declaration of other_sub?

I'm afraid I don't understand the question.

To many unclear referents, notably I have no idea what "this" refers to.
I'm also puzzled by the business about "in the case of implicit none"
because the code in question does have implicit none. If your "this"
refers to the OP's code, then no, there is no implicit declaration of
other_sub. Other_sub is declared about as explicitly as can be in that
the actual subroutine is in the module.

For that matter, implicit none never has anything at all to do with
subroutines. It has only to do with types, and subroutines don't have
types.

glen herrmannsfeldt

unread,
Sep 23, 2008, 3:08:32 AM9/23/08
to
Richard Maine wrote:
(snip, I wrote)

>>In the case of IMPLICIT NONE, is this an implicit
>>declaration of other_sub?

> I'm afraid I don't understand the question.

> To many unclear referents, notably I have no idea what "this" refers to.
> I'm also puzzled by the business about "in the case of implicit none"
> because the code in question does have implicit none. If your "this"
> refers to the OP's code, then no, there is no implicit declaration of
> other_sub. Other_sub is declared about as explicitly as can be in that
> the actual subroutine is in the module.

Yes, that is the question I was asking. At the point that it is
used, there is no declaration, which is also explicit declaration
for a subroutine.

> For that matter, implicit none never has anything at all to do with
> subroutines. It has only to do with types, and subroutines don't have
> types.

In C void functions pointers have type ((void*)()), In PL/I
they have the ENTRY attribute. (Both languages allow variables
to hold such, so they need a way to declare them.)

-- glen

robert....@sun.com

unread,
Sep 23, 2008, 2:56:18 AM9/23/08
to
On Sep 19, 11:25 pm, nos...@see.signature (Richard Maine) wrote:

Yes, I misread his example. I thought other_sub was an
external procedure.

Bob Corbett

Rich Townsend

unread,
Sep 23, 2008, 9:43:37 AM9/23/08
to

Can I briefly remark that your suggested workaround -- putting in a redundant
private/public statement at the top of the module -- worked a treat. Thanks!

cheers,

Rich

Richard Maine

unread,
Sep 23, 2008, 1:17:18 PM9/23/08
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> At the point that it is used, there is no declaration, which is also
> explicit declaration for a subroutine.

I cannot agree that "no declaration...is also explicit declaration".

Perhaps you meant to say that because there is no local declaration, the
entity of that name from the host is accessed by host association.
That's so. That also has nothing in particular to do with subroutines;
it's just how host association works in general.

If that's not what you meant, then I'm pretty sure I disagree because I
can't think of any other plausible meaning that I'd agree with.

> Richard Maine wrote:

> > For that matter, implicit none never has anything at all to do with
> > subroutines. It has only to do with types, and subroutines don't have
> > types.
>
> In C void functions pointers have type ((void*)()), In PL/I
> they have the ENTRY attribute. (Both languages allow variables
> to hold such, so they need a way to declare them.)

Fortran isn't C (or PL/I). Subroutines do not have a type, not even an
equivalent of void type. This occasionally leads to awkwardness in
wording of the standard. For example, there is at least one place,
perhaps more (and I don't feel like searching for them) where the
standard talks about agreement in type, but then has to make a special
case for both things in question being subroutines. I might have thought
that both things not having a type would constitute agreement in type,
but the standard doesn't take that path.

You can declare subroutines in Fortran by any of quite a few means
(interface body, procedure statement, external statement), but not in a
type declaration statement.

paul.rich...@gmail.com

unread,
Nov 4, 2008, 4:55:19 PM11/4/08
to
This is now fixed on gcc-4.4 and, in a week, will be fixed on gcc-4.3.

Thanks for the report.

Paul

0 new messages