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

question on overloading function names

49 views
Skip to first unread message

Nasser M. Abbasi

unread,
Feb 17, 2012, 3:09:30 AM2/17/12
to
To overload function names, I am reading that one needs to make
an interface.

As I am learning Fortran, I'd like to keep everything in one file for
now to make life simpler.

How can one add this interface to the same file, so that the
following toy program will compile?

I am overloading foo() below, and so I think I need to add

interface foo
module subroutine foo
end interface

somewhere.

But not sure where to do this, and again, trying to keep everything
in the same file. I'd like to keep the foo() subroutines in the same
file.

-----------------------------------
program f04
implicit none
complex, parameter :: x= CMPLX(0,2.0*ACOS(0.0))
integer, parameter :: y=5

CALL foo(x)
CALL foo(y)

CONTAINS
subroutine foo(arg)
implicit none
real, intent(in) :: arg
print *, arg
end subroutine foo

subroutine foo(arg)
implicit none
complex, intent(in) :: arg
print *, arg
end subroutine foo

end program f04
------------------------------

thanks,

--Nasser

Nasser M. Abbasi

unread,
Feb 17, 2012, 3:12:24 AM2/17/12
to
On 2/17/2012 2:09 AM, Nasser M. Abbasi wrote:

>
> -----------------------------------
> program f04
> implicit none
> complex, parameter :: x= CMPLX(0,2.0*ACOS(0.0))
> integer, parameter :: y=5
>
> CALL foo(x)
> CALL foo(y)
>
> CONTAINS
> subroutine foo(arg)
> implicit none
> real, intent(in) :: arg
> print *, arg
> end subroutine foo
>
> subroutine foo(arg)
> implicit none
> complex, intent(in) :: arg
> print *, arg
> end subroutine foo
>
> end program f04
> ------------------------------
>

opps, I better replace 'integer' by 'real' above, here it is again:

------------------------------
program f04
implicit none
complex, parameter :: x= CMPLX(0,2.0*ACOS(0.0))
integer, parameter :: y=5

CALL foo(x)
CALL foo(y)


CONTAINS
subroutine foo(arg)
implicit none
integer, intent(in) :: arg
print *, arg
end subroutine foo

subroutine foo(arg)
implicit none
complex, intent(in) :: arg
print *, arg
end subroutine foo

end program f04
---------------------------------

--Nasser

Aris

unread,
Feb 17, 2012, 3:55:09 AM2/17/12
to
module foo_mod
implicit none
interface foo
module procedure foo_i,foo_c
end interface
contains
subroutine foo_i(arg)
integer, intent(in) :: arg
print *, arg
end subroutine

subroutine foo_c(arg)
complex, intent(in) :: arg
print *, arg
end subroutine
end module

program f04
use foo_mod
implicit none

complex, parameter :: x= CMPLX(0,2.0*ACOS(0.0))
integer, parameter :: y=5

CALL foo(x)
CALL foo(y)

end program f04

Tobias Burnus

unread,
Feb 17, 2012, 4:20:21 AM2/17/12
to
On 02/17/2012 09:09 AM, Nasser M. Abbasi wrote:
> I am overloading foo() below, and so I think I need to add
>
> interface foo
> module subroutine foo
> end interface
>
> somewhere.

See Aris' answer when using modules. With Fortran 2003, you can also use
the following, which also works without modules (place it in before the
"CALL" in your program):

interface foo
procedure foo_c, foo_i
end interface

Contrary to Aris' example, it's only "procedure" and not "module
procedure" - the latter is only allowed if the specific procedures are
in a module (more precisely: are module procedures).

And you need to rename at least one of the specific procedures
("subroutine foo"); it is probably less confusing if you rename both -
as Aris and I did.

Tobias

Nasser M. Abbasi

unread,
Feb 17, 2012, 5:42:28 AM2/17/12
to
Thanks. I tried yours, but to be clear, let me show the full
layout now as I get compiler error, this tells me I did not
understand exactly what you meant. It works when I have a separate
foo_mod.f90 file for the interface.

----- file f05.f90----------
program f05
implicit none

complex, parameter :: x= CMPLX(0,2.0*ACOS(0.0))
integer, parameter :: y=5

interface foo
procedure foo_c, foo_i
end interface foo

CALL foo(x)
CALL foo(y)

contains
subroutine foo_i(arg)
integer, intent(in) :: arg
print *, arg
end subroutine foo_i

subroutine foo_c(arg)
complex, intent(in) :: arg
print *, arg
end subroutine foo_c

end program f05
-------------------------

$gfortran -std=f2003 f05.f90
f05.f90:15.18:

subroutine foo_i(arg)
1
Error: Extension: Internal procedure 'foo_i' in generic interface 'foo' at (1)

$gfortran -v
gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3)

thanks,
--Nasser

m_b_metcalf

unread,
Feb 17, 2012, 6:13:27 AM2/17/12
to
> --Nasser- Zitierten Text ausblenden -
>
> - Zitierten Text anzeigen -

Nasser,
You make an interface explicit EITHER by using the procedure from
a module, OR by making the procedure an internal procedure, OR by
having an interface block. The first two are the usual way. The third
is required only for procedures passed as arguments (see MFE, Section
5.12). But, only one way can be used at a time.

HTH

Mike Metcalf

JWM

unread,
Feb 17, 2012, 6:13:44 AM2/17/12
to
The error is telling you that gfortran still classifies that as an (GNU)
extension to the standard (I think it should be a warning, instead of an
error, but I guess that's just gfortran's way of dealing with non-standard
stuff). If you remove the "-std=f2003" flag, or use "-std=gnu", it should
compile just fine.

--
John

Nasser M. Abbasi

unread,
Feb 17, 2012, 6:26:30 AM2/17/12
to
On 2/17/2012 5:13 AM, JWM wrote:

>
> The error is telling you that gfortran still classifies that as an (GNU)
> extension to the standard (I think it should be a warning, instead of an
> error, but I guess that's just gfortran's way of dealing with non-standard
> stuff). If you remove the "-std=f2003" flag, or use "-std=gnu", it should
> compile just fine.
>

Yes, it compiles OK with -std=gnu

$gfortran -std=gnu f05.f90
$

When Tobias said it will work with fortran 2003, I misunderstood
this to mean to use -std=f2003.

modules and interfaces in Fortran is all new to me,
I need to learn more about them. I stopped Fortran at
Fortran 77 :)

Thanks to everyone for the help
--Nasser

Tobias Burnus

unread,
Feb 17, 2012, 6:37:38 AM2/17/12
to
On 02/17/2012 12:13 PM, JWM wrote:
> On Fri, 17 Feb 2012 03:42:28 -0700, Nasser M. Abbasi <n...@12000.org> wrote:
>> $gfortran -std=f2003 f05.f90
>> f05.f90:15.18:
>>
>> subroutine foo_i(arg)
>> 1
>> Error: Extension: Internal procedure 'foo_i' in generic interface
>> 'foo' at (1)


Sorry, my fault. I thought that this is allowed in Fortran 2003. (Using
"procedure" instead of "module procedure" is new in Fortran 2003.)

However, using internal procedures in generic interfaces seems to be new
since Fortran 2008.

Additionally, gfortran has the bug that it does not accept them with
-std=f2008 but only as vendor extension (-std=gnu). Sorry for the confusion.


Using an internal procedure is not allowed in Fortran 2003:

C1207 (R1206) A procedure-name shall have an explicit interface and
shall refer to an accessible procedure pointer, external procedure,
dummy procedure, or module procedure.


However, it is allowed in Fortran 2008:

C1207 (R1206) A procedure-name shall be a nonintrinsic procedure that
has an explicit interface.


Thus, you either need to use a module [or less useful alternatives] - or
compile without -std=f2003.


> The error is telling you that gfortran still classifies that as an (GNU)
> extension to the standard (I think it should be a warning, instead of an
> error, but I guess that's just gfortran's way of dealing with
> non-standard stuff). If you remove the "-std=f2003" flag, or use
> "-std=gnu", it should compile just fine.

I believe printing an error is the only sensible choice if the user as
explicitly asked for Fortran 2003 conformity.

Tobias

PS: I will fill a bugreport regarding -std=f2008.

Nasser M. Abbasi

unread,
Feb 17, 2012, 7:23:46 AM2/17/12
to
On 2/17/2012 5:26 AM, Nasser M. Abbasi wrote:
> On 2/17/2012 5:13 AM, JWM wrote:
>
>>
>> The error is telling you that gfortran still classifies that as an (GNU)
>> extension to the standard (I think it should be a warning, instead of an
>> error, but I guess that's just gfortran's way of dealing with non-standard
>> stuff). If you remove the "-std=f2003" flag, or use "-std=gnu", it should
>> compile just fine.
>>
>
> Yes, it compiles OK with -std=gnu
>
> $gfortran -std=gnu f05.f90
> $
>

fyi,

I like to compile with -pedantic in there, so when I added that, the
error came back:

--------------------------
$gfortran -std=gnu -pedantic f05.f90
f05.f90:15.18:

subroutine foo_i(arg)
1
Warning: Extension: Internal procedure 'foo_i' in generic interface 'foo' at (1)
f05.f90:20.18:

subroutine foo_c(arg)
1
Warning: Extension: Internal procedure 'foo_c' in generic interface 'foo' at (1)
------------------------------

so, I think I'll stick with separate module file for now, since
that compiles clean with all the flags that I have
(-Wextra -Wall -pedantic -fcheck=all)

--Nasser

Aris

unread,
Feb 17, 2012, 8:49:25 AM2/17/12
to
"Nasser M. Abbasi" <n...@12000.org> wrote:
>
> fyi,
>
> I like to compile with -pedantic in there, so when I added that, the
> error came back:
>
> --------------------------
> $gfortran -std=gnu -pedantic f05.f90
> f05.f90:15.18:
>
> subroutine foo_i(arg)
> 1
> Warning: Extension: Internal procedure 'foo_i' in generic interface 'foo' at (1)
> f05.f90:20.18:
>
> subroutine foo_c(arg)
> 1
> Warning: Extension: Internal procedure 'foo_c' in generic interface 'foo' at (1)
> ------------------------------
>
> so, I think I'll stick with separate module file for now, since
> that compiles clean with all the flags that I have
> (-Wextra -Wall -pedantic -fcheck=all)

A warning is not an error.
And you do realize that the module does not have to be in a separate
file, right?

James Van Buskirk

unread,
Feb 17, 2012, 10:07:47 AM2/17/12
to
"Tobias Burnus" <bur...@net-b.de> wrote in message
news:4F3E1BD5...@net-b.de...

> And you need to rename at least one of the specific procedures
> ("subroutine foo"); it is probably less confusing if you rename both - as
> Aris and I did.

No you don't. This is an important point as far as I'm concerned
because I not infrequently create generic functions as copies of
one master function via INCLUDE. Doing so means all changes may
be preserved in a single file rather than having to keep track
of all different copies of what is really the same function and
modifying each separately. This requires that each procedure
have the same name. Here is my example:

C:\gfortran\clf\overload>type overload.f90
module integer_mod
implicit none
private
public foo_public
interface foo_public
module procedure foo
end interface foo_public
contains
subroutine foo(arg)
integer, intent(in) :: arg
print *, arg
end subroutine foo
end module integer_mod

module complex_mod
implicit none
private
public foo_public
interface foo_public
module procedure foo
end interface foo_public
contains
subroutine foo(arg)
complex, intent(in) :: arg
print *, arg
end subroutine foo
end module complex_mod

module foo_mod
use integer_mod, only: foo => foo_public
use complex_mod, only: foo => foo_public
implicit none
end module foo_mod

program f04
use foo_mod
implicit none
complex, parameter :: x= CMPLX(0,2.0*ACOS(0.0))
integer, parameter :: y=5

CALL foo(x)
CALL foo(y)
end program f04

C:\gfortran\clf\overload>gfortran overload.f90 -ooverload

C:\gfortran\clf\overload>overload
( 0.0000000 , 3.1415927 )
5

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


Aris

unread,
Feb 17, 2012, 10:15:38 AM2/17/12
to
"James Van Buskirk" <not_...@comcast.net> wrote:
> "Tobias Burnus" <bur...@net-b.de> wrote in message
> news:4F3E1BD5...@net-b.de...
>
>> And you need to rename at least one of the specific procedures
>> ("subroutine foo"); it is probably less confusing if you rename both - as
>> Aris and I did.
>
> No you don't. This is an important point as far as I'm concerned
> because I not infrequently create generic functions as copies of
> one master function via INCLUDE. Doing so means all changes may
> be preserved in a single file rather than having to keep track
> of all different copies of what is really the same function and
> modifying each separately. This requires that each procedure
> have the same name. Here is my example:

So you are naming the modules differently.
And the routines cannot be exactly the same, the declarations have
to be different. So you can just as well put routines with different
namens in one module, and put only the body of the routines in
include files.

module foo_mod
implicit none
interface foo
module procedure foo_i,foo_c
end interface
contains
subroutine foo_i(arg)
integer, intent(in) :: arg
include 'foo_body.h90'
end subroutine

subroutine foo_c(arg)
complex, intent(in) :: arg
include 'foo_body.h90'
end subroutine
end module

James Van Buskirk

unread,
Feb 17, 2012, 10:25:20 AM2/17/12
to
"Aris" <us...@3h1bgd.invalid> wrote in message
news:jhlquq$u24$1...@news.albasani.net...

> "James Van Buskirk" <not_...@comcast.net> wrote:

>> No you don't. This is an important point as far as I'm concerned
>> because I not infrequently create generic functions as copies of
>> one master function via INCLUDE. Doing so means all changes may
>> be preserved in a single file rather than having to keep track
>> of all different copies of what is really the same function and
>> modifying each separately. This requires that each procedure
>> have the same name. Here is my example:

> So you are naming the modules differently.
> And the routines cannot be exactly the same, the declarations have
> to be different. So you can just as well put routines with different
> namens in one module, and put only the body of the routines in
> include files.

Fallacy upon fallacy! It seems another example is required:

C:\gfortran\clf\overload>type overload.i90
subroutine foo(Qarg)
intent(in) :: Qarg
print *, Qarg
end subroutine foo

C:\gfortran\clf\overload>type overload2.f90
module integer_mod
implicit integer(Q)
private
public foo_public
interface foo_public
module procedure foo
end interface foo_public
contains
include 'overload.i90'
end module integer_mod

module complex_mod
implicit complex(Q)
private
public foo_public
interface foo_public
module procedure foo
end interface foo_public
contains
include 'overload.i90'
end module complex_mod

module foo_mod
use integer_mod, only: foo => foo_public
use complex_mod, only: foo => foo_public
implicit none
end module foo_mod

program f04
use foo_mod
implicit none
complex, parameter :: x= CMPLX(0,2.0*ACOS(0.0))
integer, parameter :: y=5

CALL foo(x)
CALL foo(y)
end program f04

C:\gfortran\clf\overload>gfortran overload2.f90 -ooverload2

C:\gfortran\clf\overload>overload2
( 0.0000000 , 3.1415927 )
5

In this case the routines are exactly the same source code as
guaranteed by INCLUDE.

Aris

unread,
Feb 17, 2012, 10:58:56 AM2/17/12
to
"James Van Buskirk" <not_...@comcast.net> wrote:
> "Aris" <us...@3h1bgd.invalid> wrote in message
> news:jhlquq$u24$1...@news.albasani.net...
>
>> "James Van Buskirk" <not_...@comcast.net> wrote:
>
>>> No you don't. This is an important point as far as I'm concerned
>>> because I not infrequently create generic functions as copies of
>>> one master function via INCLUDE. Doing so means all changes may
>>> be preserved in a single file rather than having to keep track
>>> of all different copies of what is really the same function and
>>> modifying each separately. This requires that each procedure
>>> have the same name. Here is my example:
>
>> So you are naming the modules differently.
>> And the routines cannot be exactly the same, the declarations have
>> to be different. So you can just as well put routines with different
>> namens in one module, and put only the body of the routines in
>> include files.
>
> Fallacy upon fallacy! It seems another example is required:

I refuse to use implicit ;-)
0 new messages