From: monir on
Hello;

1) I'm trying to convert one of my algorithms from F77 to F90 and
having some difficulties as to when (and when not!) to declare the
function as EXTERNAL within a module.

2) Some basic MODULES are set at the top, followed by MODULE
Work_Routines, which contains all of the subroutines and functions,
and then the main Program.
ALL in one file.
The problem appears to be generated in the Work_Routines module,
resulting in compilation errors referring to the functions names
throughout.
For example:
(with g95 0.92! 2009 Fortran compiler)
....C:\......:Test-M2.F90:(.data+0x78): UNDEFINED reference to
`_dcpval_`

3) Here's an abbreviated sample code:
[Sub Test() uses fun ZBR() which in turn uses fun dCpVal as argument]

EXAMPLE 1:
==========

MODULE Work_Routines
!............
SUBroutine Test()
implicit none
double precision ZBR, dCpVal, dc
External dCpVal !<<<<<
.................................
dc = ZBR(dCpVal, ....., ......)
return
End Subroutine Test

FUNction ZBR(func, ...,...,...)
implicit double precision (a-h,o-z)
double precision func
..................................
ZBR = ....
return
End Function ZBR

!............
FUNction dCpVal(x)
implicit none
double precision dCpVal
.......................
dCpVal = ...
return
End Function dCpVal

End MODULE Work_Routines

3) Commenting out "External dCpVal" in Sub Test() above appears to
solve the problem, with no more "Undefined references".

4) So I concluded:
....IF the external function is in a MODULE, then:
....i. if the function name DOES NOT appear in the arg list of the
calling routine within the module, then DO NOT declare the function
(e.g.; dCpVal in the above example) as External. Only declare its
type.
...ii. If the function name appears in the argument list, then declare
the function as External.

5) Apparently that's incorrect!

EXAMPLE2 below DOES NOT work:
....Error: Actual parameter 'func2' at (1) is not a PROCEDURE
with (1) referring to argument "FunPath" in Call QROM () below.

Activating the declaration " !? External FunPath" results in many
"UNDEFINED references, incl:
....C:\......:Test-M2.F90:(.text+0x10725c): undefined reference to
`_funpath_'

EXAMPLE 2:
==========

MODULE Work_Routines2

SUBroutine Path()
implicit none
............................
double precision FunPath
!? External FunPath
...........................
Call QROM(FunPath, ....,.....,.....) !!<<$$
...........................
return
End Subroutine Path

SUBroutine QROM (FUNC2,....,....,....)
implicit none
double precision FUNC2
External FUNC2
............................
CALL Trap(FUNC2,..,..,..)
End Subroutine QROM

SUBroutine Trap (FUNC,..,..,..)
implicit none
double precision FUNC
External FUNC
...........................
...........................
End Subroutine Trap

End MODULE Work_Routines2


Can someone please help ??

Thank you kindly.
Monir
From: steve on
On Jul 27, 10:18 am, monir <mon...(a)rogers.com> wrote:
>
> Can someone please help ??
>

Get out your favorite F90/95/2003 book and
read about implicit and explicit interfaces.
This should help you sort out some of your
confusion.

--
steve
From: Richard Maine on
monir <monirg(a)rogers.com> wrote:

> 1) I'm trying to convert one of my algorithms from F77 to F90 and
> having some difficulties as to when (and when not!) to declare the
> function as EXTERNAL within a module.

You should always declare an external function as external when you
reference it. It isn't required in all cases, but it is a good idea for
several reasons. It is not a good idea to quibble about the fine details
of exactly when you can get by without it. I half suspect that some
people might post those rules, but it doesn't matter. Just do it anyway.
That's particularly so if you are having trouble with the simple rules
like distinguishing between module and externalI; no need to distract
yourself with subtle points that you don't actually even need to know.
If you have an interface body for the function, then that constitutes an
external declaration (even though it doesn't use the keyword external),
so you would not do both an interface body and an external statement or
attribute.

***BUT***

The procedures in your example are not external procedures. They are
module procedures. The two are *NOT* at all the same thing. If you
declare them to be external procedures, then you would be lying to the
compiler and it won't work. It will look for an external procedure of
that name, which you don't have.

Also, don't declare the type of a module procedure where you reference
it. In fact, don't ever declare anything about a module procedure except
within the procedure itself. When you USE the module, the USE statement
brings in all the information needed. You do not need to redeclare it;
nor are you allowed to. Don't redeclare module procedures within the
module either; that also isn't allowed and will make the compiler think
you are trying to declare something else instead.

> ..ii. If the function name appears in the argument list, then declare
> the function as External.
>
> 5) Apparently that's incorrect!

Well it is certainly incorrect in that you did not distingiush between
actual argument lists and dummy argument lists. They are not at all the
same.

You should declare a dummy procedure to be a procedure. Use either an
interface body or an external statement. A dummy procedure is its own
thing - the dummy. It does not matter whether it might happen to have
the same name as some external or module procedure or anything else;
those are different things. They might end up being used as actual
procedures associated with the dummy, but that doesn't constitute
declaring anything about the dummy.

> EXAMPLE2 below DOES NOT work:
> ...Error: Actual parameter 'func2' at (1) is not a PROCEDURE
> with (1) referring to argument "FunPath" in Call QROM () below.

Well, yes. because you have done nothing to tell the compiler it is a
procedure. Declarations somewhere else don't matter. Just look in the
routine where you use funpath as an actual argument. Do you see anything
that says funpath is a procedure? I don't. Neither does the compiler. It
can't read minds.

> Activating the declaration " !? External FunPath" results in many
> "UNDEFINED references, incl:
> ...C:\......:Test-M2.F90:(.text+0x10725c): undefined reference to
> `_funpath_'

Probably because there isn't an external procedure named funpath
anywhere. I don't see one in anything you posted. Declaring funpath to
be external tells the compiler to look for such a thing, but you still
have to actually have it.

Since you don't show even a hint as to where this funpath might be, I
don't have a lot to go on. The three possibilities that occur to me are

1. The most obvious one - you don't have a funpath procedure.

2. A slight variant in that you have a funpath procedure, but have not
linked it into your program. That's pretty much the same as not having
one, except that you might confuse yourself by looking at code that
isn't part of the program.

3. You have a funpath, but it is a module procedure instead of an
external one. See prior stuff about module procedures, and repeat about
a thousand times "'module' is not the same thing as 'external'". Don't
declare a module procedure to be external; USE the module instead.

>
> EXAMPLE 2:
> ==========
>
> MODULE Work_Routines2
>
> SUBroutine Path()
> implicit none
> ............................
> double precision FunPath
> !? External FunPath
> ...........................
> Call QROM(FunPath, ....,.....,.....) !!<<$$
> ...........................
> return
> End Subroutine Path
>
> SUBroutine QROM (FUNC2,....,....,....)
> implicit none
> double precision FUNC2
> External FUNC2
> ............................
> CALL Trap(FUNC2,..,..,..)
> End Subroutine QROM
>
> SUBroutine Trap (FUNC,..,..,..)
> implicit none
> double precision FUNC
> External FUNC
> ...........................
> ...........................
> End Subroutine Trap
>
> End MODULE Work_Routines2
>
>
> Can someone please help ??
>
> Thank you kindly.
> Monir


--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: monir on
On Jul 27, 3:00 pm, nos...(a)see.signature (Richard Maine) wrote:
> monir <mon...(a)rogers.com> wrote:
>

Thank you for your replies.
Sorry, I forgot to post Function funpath(t) in EXAMPLE 2.
It's included in: Module Work_Routines

EXAMPLE 2:
==========

MODULE Work_Routines2

SUBroutine Path()
implicit none
............................
double precision FunPath
!? External FunPath
...........................
Call QROM(FunPath, ....,.....,.....) !!<<$$
...........................
return
End Subroutine Path

SUBroutine QROM (FUNC2,....,....,....)
implicit none
double precision FUNC2
External FUNC2
............................
CALL Trap(FUNC2,..,..,..)
End Subroutine QROM

SUBroutine Trap (FUNC,..,..,..)
implicit none
double precision FUNC
External FUNC
...........................
...........................
End Subroutine Trap

FUNction FunPath(t)
implicit none
double precision FunPath, t
....................
FunPath = ....
return
End Function FunPath

End MODULE Work_Routines2

Regards.
Monir
From: Richard Maine on
monir <monirg(a)rogers.com> wrote:

> On Jul 27, 3:00 pm, nos...(a)see.signature (Richard Maine) wrote:
> > monir <mon...(a)rogers.com> wrote:
> >
>
> Thank you for your replies.
> Sorry, I forgot to post Function funpath(t) in EXAMPLE 2.
> It's included in: Module Work_Routines

Than, as with other cases of module routines, don't declare it external
(it isn't), and don't reclare its type. Declaring a type for it like you
did keeps the module procedure from being host associated into where you
need it. The compiler thinks it is either a variable or an external
procedure depending on whether or not you also have the external
declaration.

If it was in a different module, you'd need to USE the module. But as it
is in the same one, just don't do anything else to declare it. Any such
attempts will just do harm.

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