From: Thomas Robitaille on
Hello,

I am using a fortran library that provides subroutines that are
already overloaded, and I would like to overload them further, but I
can't seem to be able to do that. Consider the following example:

module a
interface do
module procedure do_real, do_str
end interface
contains
subroutine do_real(x)
real,intent(in) :: x
end subroutine do_real
subroutine do_str(x)
character(len=*),intent(in) :: x
end subroutine do_str
end module a

module b
use a, do_old => do
interface do
module procedure do_old, do_int
end interface do
contains
subroutine do_int(x)
integer,intent(in) :: x
end subroutine do_int
end module b

This does not compile, giving the following error with ifort:

test.f90(17): error #7950: Procedure name in MODULE PROCEDURE
statement must be the name of accessible module procedure. [DO_OLD]
module procedure do_old, do_int
---------------------^

compilation aborted for test.f90 (code 1)

Of course, I could change the module procedure in the 'b' module to

module procedure do_str, do_real, do_int

so as to overload 'do' from scratch, but in practice, the subroutine I
am overloaded already contains 20-30 routines, so I don't want to have
to list them all again.

Is there a workaround for this?

Thanks in advance for any advice,

Thomas
From: Richard Maine on
Thomas Robitaille <thomas.robitaille(a)gmail.com> wrote:

> Hello,
>
> I am using a fortran library that provides subroutines that are
> already overloaded, and I would like to overload them further, but I
> can't seem to be able to do that. Consider the following example:
>
> module a
> interface do
> module procedure do_real, do_str
> end interface
> contains
> subroutine do_real(x)
> real,intent(in) :: x
> end subroutine do_real
> subroutine do_str(x)
> character(len=*),intent(in) :: x
> end subroutine do_str
> end module a
>
> module b
> use a, do_old => do
> interface do
> module procedure do_old, do_int
> end interface do
> contains
> subroutine do_int(x)
> integer,intent(in) :: x
> end subroutine do_int
> end module b
>
> This does not compile, giving the following error with ifort:
>
> test.f90(17): error #7950: Procedure name in MODULE PROCEDURE
> statement must be the name of accessible module procedure....

Yes. The module procedure statement is for specifying specific
procedures to include in a generic. Your old_do is not a specific
procedure; it is a generic one.

But I think you are just making things much more complicated than they
need to be. You seem to be trying to create a new generic (even though
using the same name as the old one). Instead, just extend the old one.
The language specifically allows that. In particular, drop the rename
in the USE statement, making it just

use a

Then drop the old_do from the module procedure statement in b, making it

module procedure do_init

I just made those edits to your code and compiled it with the NAG
compiler. Compiled fine (warning about the unused dummy arguments, but
that's not the point here).

> Is there a workaround for this?

I wouldn't actually call this a workaround. This is the way generic
procedure extension is designed to work. I think that perhaps you might
have thought that you could not import a generic name and then extend
that same generic name. If you import almost anything else via USE, you
can't change things about it locally. But generics are special that way.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: Walt Brainerd on
On 7/2/2010 3:03 PM, Thomas Robitaille wrote:
> Hello,
>
> I am using a fortran library that provides subroutines that are
> already overloaded, and I would like to overload them further, but I
> can't seem to be able to do that. Consider the following example:
>
> module a
> interface do
> module procedure do_real, do_str
> end interface
> contains
> subroutine do_real(x)
> real,intent(in) :: x
> end subroutine do_real
> subroutine do_str(x)
> character(len=*),intent(in) :: x
> end subroutine do_str
> end module a
>
> module b
> use a, do_old => do
> interface do
> module procedure do_old, do_int
> end interface do
> contains
> subroutine do_int(x)
> integer,intent(in) :: x
> end subroutine do_int
> end module b
>
> This does not compile, giving the following error with ifort:
>
> test.f90(17): error #7950: Procedure name in MODULE PROCEDURE
> statement must be the name of accessible module procedure. [DO_OLD]
> module procedure do_old, do_int
> ---------------------^
>
> compilation aborted for test.f90 (code 1)
>
> Of course, I could change the module procedure in the 'b' module to
>
> module procedure do_str, do_real, do_int
>
> so as to overload 'do' from scratch, but in practice, the subroutine I
> am overloaded already contains 20-30 routines, so I don't want to have
> to list them all again.
>
> Is there a workaround for this?
>
> Thanks in advance for any advice,
>
> Thomas

I am not sure why you want to do the rename.
Does the followiing do what you want?

module a
interface do
module procedure do_real, do_str
end interface
contains
subroutine do_real(x)
real,intent(in) :: x
print *, "real", x
end subroutine do_real
subroutine do_str(x)
character(len=*),intent(in) :: x
print *, "char", trim(x)
end subroutine do_str
end module a

module b
use a
interface do
module procedure do_int
end interface do
contains
subroutine do_int(x)
integer,intent(in) :: x
print *, "integer", x
end subroutine do_int
end module b

program p
use b
implicit none
call do(9)
call do(9.9)
call do("9")
end program p

--
Walt Brainerd