Passing module procedures to external procedures -- type issues 
Author Message
 Passing module procedures to external procedures -- type issues

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



Wed, 09 Mar 2011 09:52:32 GMT  
 Passing module procedures to external procedures -- type issues

Quote:

> 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.

Quote:
> 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?

Quote:
> 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



Wed, 09 Mar 2011 13:15:06 GMT  
 Passing module procedures to external procedures -- type issues

Quote:
> 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?

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



Wed, 09 Mar 2011 13:06:05 GMT  
 Passing module procedures to external procedures -- type issues

Quote:

> > 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?

> 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.

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

Bob Corbett



Wed, 09 Mar 2011 13:16:55 GMT  
 Passing module procedures to external procedures -- type issues

Quote:


> > 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



Wed, 09 Mar 2011 14:25:34 GMT  
 Passing module procedures to external procedures -- type issues
Tobias Burnus posted this as PR35597 and I just confirmed it.

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

Cheers

Paul



Fri, 11 Mar 2011 03:39:50 GMT  
 Passing module procedures to external procedures -- type issues

Quote:
> 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



Fri, 11 Mar 2011 07:11:53 GMT  
 Passing module procedures to external procedures -- type issues

Quote:



>>> 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.

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



Fri, 11 Mar 2011 11:02:21 GMT  
 Passing module procedures to external procedures -- type issues

Quote:

> 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!)



Fri, 11 Mar 2011 11:03:22 GMT  
 Passing module procedures to external procedures -- type issues

Quote:

> 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.)

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



Fri, 11 Mar 2011 11:20:26 GMT  
 Passing module procedures to external procedures -- type issues

Quote:

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

       call QAG(other_sub)
Quote:
>     end subroutine internal_sub
>   end subroutine main_sub
>   subroutine other_sub ()
>   end subroutine other_sub
> end module foo

(snip)

Quote:
>       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



Sat, 12 Mar 2011 07:09:26 GMT  
 Passing module procedures to external procedures -- type issues
(snip)

Quote:
> 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



Sat, 12 Mar 2011 12:47:29 GMT  
 Passing module procedures to external procedures -- type issues

Quote:

> ...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.

Quote:
> 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.

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



Sat, 12 Mar 2011 13:47:00 GMT  
 Passing module procedures to external procedures -- type issues
(snip, I wrote)

Quote:
>>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.

Quote:
> 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



Sat, 12 Mar 2011 15:08:32 GMT  
 Passing module procedures to external procedures -- type issues

Quote:


> > > 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.

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

Bob Corbett



Sat, 12 Mar 2011 14:56:18 GMT  
 
 [ 18 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Passing procedures as parameters to procedures.

2. Passing multiple paramaters when linking an external asm procedure in c++

3. procedure variables vs. type-bound procedures

4. array-valued procedure: I/O reccursion with module procedure

5. Module interfaces and external procedures

6. passing pointer of different type to one procedure

7. Passing type-bound procedures as arguments?

8. use module to pass data between procedures

9. Are procedure types breaking modules?

10. Access types vs. Record types as procedure parameters

11. A Type checking/reconstruction procedure for Typed-Prolog

12. type-bound procedures and type extension

 

 
Powered by phpBB® Forum Software