From: michael on

I have a question to externals in modules, as illustrated below. I would
think that the interface specification would tell RUKU that fun is an
external, but G95 requires the additional external fun statement, whereas
other compilers (Lahey, CVF) does not.

What are the exact requirements for specification of procedure arguments
to module subprograms?


MODULE otestx
interface
subroutine fun(y,f)
double precision y,f
end subroutine
end interface
private
public ruku
CONTAINS
SUBROUTINE RUKU (Y,h,fun)
external fun ! Is this needed ?
double precision y,h,f
double precision k1,k2,k3,k4
call fun(y,f)
k1 = h*f
call fun(y+0.5*k1,f)
k2 = h*f
call fun(y+0.5*k2,f)
k3 = h*f
call fun(y+k3,f)
k4=h*f
y = y + (k1+2*k2+2*k3+k4)/6.d0
END subroutine
end module
program testg
use otestx
double precision x,h
external fnc
x=4
h=0.1d0
call ruku(x,h,fnc)
print *,x
end
subroutine fnc(y,f)
double precision y,f
f = y+1
end

From: Arjen Markus on
On 20 jun, 15:34, m...(a)kt.dtu.dk (michael) wrote:
> I have a question to externals in modules, as illustrated below. I would
> think that the interface specification would tell RUKU that fun is an
> external, but G95 requires the additional external fun statement, whereas
> other compilers (Lahey, CVF) does not.
>
> What are the exact requirements for specification of procedure arguments
> to module subprograms?
>
>       MODULE otestx
>       interface
>          subroutine fun(y,f)
>           double precision y,f
>          end subroutine
>       end interface
>       private
>       public ruku
>       CONTAINS
>       SUBROUTINE RUKU (Y,h,fun)
>        external fun                    ! Is this needed ?
>        double precision y,h,f
>        double precision k1,k2,k3,k4
>        call fun(y,f)
>        k1 = h*f
>        call fun(y+0.5*k1,f)
>        k2 = h*f
>        call fun(y+0.5*k2,f)
>        k3 = h*f
>        call fun(y+k3,f)
>        k4=h*f
>        y = y + (k1+2*k2+2*k3+k4)/6.d0
>       END subroutine
>       end module
>       program testg
>       use otestx
>       double precision x,h
>       external fnc
>       x=4
>       h=0.1d0
>       call ruku(x,h,fnc)
>       print *,x
>       end
>       subroutine fnc(y,f)
>        double precision y,f
>        f = y+1
>       end

You should move the interface block after the subroutine statement.
Now the compiler has no way of knowing that you mean one and the
same thing with "fun" in these two places.

Regards,

Arjen
From: Alois Steindl on
mlm(a)kt.dtu.dk (michael) writes:

> I have a question to externals in modules, as illustrated below. I would
> think that the interface specification would tell RUKU that fun is an
> external, but G95 requires the additional external fun statement, whereas
> other compilers (Lahey, CVF) does not.
>
> What are the exact requirements for specification of procedure arguments
> to module subprograms?
>
>
> MODULE otestx
> interface
> subroutine fun(y,f)
> double precision y,f
> end subroutine
> end interface
> private
> public ruku
> CONTAINS
> SUBROUTINE RUKU (Y,h,fun)
> external fun ! Is this needed ?
> double precision y,h,f

Hello,
the "fun" in the parameter list of RUKU is just a placeholder for some
routine, which could be passed to RUKU. It has no relation with fun,
whose interface is given at the beginning of otestx. (I am wondering,
what this interface declaration is useful for. Maybe it should go
within RUKU.)

Alois

From: Skip.Knoble on
On Jun 20, 9:49 am, Arjen Markus <arjen.mar...(a)wldelft.nl> wrote:
> On 20 jun, 15:34, m...(a)kt.dtu.dk (michael) wrote:
>
>
>
> > I have a question to externals in modules, as illustrated below. I would
> > think that the interface specification would tell RUKU that fun is an
> > external, but G95 requires the additional external fun statement, whereas
> > other compilers (Lahey, CVF) does not.
>
> > What are the exact requirements for specification of procedure arguments
> > to module subprograms?
>
> >       MODULE otestx
> >       interface
> >          subroutine fun(y,f)
> >           double precision y,f
> >          end subroutine
> >       end interface
> >       private
> >       public ruku
> >       CONTAINS
> >       SUBROUTINE RUKU (Y,h,fun)
> >        external fun                    ! Is this needed ?
> >        double precision y,h,f
> >        double precision k1,k2,k3,k4
> >        call fun(y,f)
> >        k1 = h*f
> >        call fun(y+0.5*k1,f)
> >        k2 = h*f
> >        call fun(y+0.5*k2,f)
> >        k3 = h*f
> >        call fun(y+k3,f)
> >        k4=h*f
> >        y = y + (k1+2*k2+2*k3+k4)/6.d0
> >       END subroutine
> >       end module
> >       program testg
> >       use otestx
> >       double precision x,h
> >       external fnc
> >       x=4
> >       h=0.1d0
> >       call ruku(x,h,fnc)
> >       print *,x
> >       end
> >       subroutine fnc(y,f)
> >        double precision y,f
> >        f = y+1
> >       end
>
> You should move the interface block after the subroutine statement.
> Now the compiler has no way of knowing that you mean one and the
> same thing with "fun" in these two places.
I think that the EXTERNAL statement in Subroutine RUKU must be
removed.
Skip Knoble
>
> Regards,
>
> Arjen

From: glen herrmannsfeldt on
michael wrote:

> I have a question to externals in modules, as illustrated below. I would
> think that the interface specification would tell RUKU that fun is an
> external, but G95 requires the additional external fun statement, whereas
> other compilers (Lahey, CVF) does not.
(snip)

Fortran 66 did not require, did not even allow for,
dummy arguments to be in an external statement.
(Probably a mistake, though.) The compiler can figure
it out when it sees the CALL statement. My belief
is that the current standards don't require it.
(If no other reason, back compatibility with old code.)
It might be that compilers do it as a back compatibility
extension, though, and that I haven't found the requirement
in the standard.

> CONTAINS
> SUBROUTINE RUKU (Y,h,fun)
> external fun ! Is this needed ?
> double precision y,h,f
> double precision k1,k2,k3,k4
> call fun(y,f)
> k1 = h*f
> call fun(y+0.5*k1,f)
> k2 = h*f
> call fun(y+0.5*k2,f)
> k3 = h*f
> call fun(y+k3,f)
> k4=h*f
> y = y + (k1+2*k2+2*k3+k4)/6.d0
> END subroutine
> end module

-- glen