(j3.2006) Question regarding the ambiguity of procedures with polymorphic arguments
Jim Xia
jimxia
Wed May 11 10:43:02 EDT 2011
My colleague's Lotus Note is playing a trick on his email:-) Here is
Rafik's previous email
Cheers,
Jim Xia
Compiler Testing, X10 & XLF
IBM Toronto Lab at 8200 Warden Ave,
Markham, On, L6G 1C7
905-413-3444
"
Hi
Sorry about the previous email. My mail client decided to turn my
message into a binary attachment. Here is the original message,
while I get the mail client issue resolved:
I think a simple example makes it clear why they're ambiguous:
type(point3d) :: a, b
... = a%add_vector(b)
The call above matches both add_vector_2d and add_vector_3d. To make
the generic interface unambiguous, you can make "vector" in add_vector_2d
take type(point2d) instead of class(point2d).
Regards
Rafik
PS XL Fortran flags the interface as ambiguous as well.
----- Forwarded by Rafik Zurob/Toronto/IBM on 11/05/2011 10:31 AM -----
From:
Rafik Zurob/Toronto/IBM
To:
fortran standards email list for J3 <j3 at j3-fortran.org>
Cc:
fortran standards email list for J3 <j3 at j3-fortran.org>,
j3-bounces at j3-fortran.org
Date:
11/05/2011 10:05 AM
Subject:
Re: (j3.2006) Question regarding the ambiguity of procedures with
polymorphic arguments
Hi
I think a simple example makes it clear why they're ambiguous:
type(point3d) :: a, b
... = a%add_vector(b)
The call above matches both add_vector_2d and add_vector_3d. To make the
generic interface unambiguous, you can make "vector" in add_vector_2d take
type(point2d) instead of class(point2d)
Regards
Rafik
PS XL Fortran flags the interface as ambiguous as well.
From:
Tobias Burnus <burnus at net-b.de>
To:
fortran standards email list for J3 <j3 at j3-fortran.org>
Date:
11/05/2011 09:32 AM
Subject:
(j3.2006) Question regarding the ambiguity of procedures with polymorphic
arguments
Sent by:
j3-bounces at j3-fortran.org
Dear all,
I have a question whether the following procedures is ambiguous (as one
compiler claims) or not (3 compilers and an older version of the first
one accept it). After initially believing that the program is valid, I
now think that it invalid. I would be happy if someone could confirm or
disprove this.
In the following, the type point3d extends point2d. The interfaces of
the two functions are:
function add_vector_2d( point, vector )
class(point2d), intent(in) :: point
class(point2d), intent(in) :: vector
function add_vector_3d( point, vector )
class(point3d), intent(in) :: point
type(point3d), intent(in) :: vector
The reason I believe that they are ambiguous is:
"Two dummy arguments are distinguishable if [...] neither is TKR
compatible with the other" (F2008, 12.4.3.4.5)
For an actual argument of the type "class(point3d),type(point3d)",
either function has the correct interface. More precisely,
class(point2d) is type compatible* with class(point3d) - and
class(point2d) is type compatible with type(point3d).
The crucial word is "neither": While add_vector_3d's dummies are
not type compatible to add_vector_2d - the reverse is not true.
Thus, the arguments are not distinguishable.
(* A polymorphic entity that is not an unlimited polymorphic entity is
type compatible with entities of the same declared type or any of its
extensions.", F2008, 4.3.1.3.)
Tobias
PS: Full example by Arjen Markus. Note, there is also a polymorphic
assignment, which makes the program definitely invalid - but it does not
matter regarding the question above.
module points2d3d implicit none
type point2d real :: x, y contains procedure
:: print => print_2d procedure
:: add_vector => add_vector_2d generic, public
:: operator(+) => add_vector end type point2d
type, extends(point2d) :: point3d real :: z contains
procedure :: print => print_3d
procedure :: add_vector_3dversion =>
add_vector_3d generic, public :: add_vector_new
=> add_vector_3dversion generic, public ::
operator(+) => add_vector_3dversion end type point3d
contains subroutine print_2d( point ) class(point2d) :: point
write(*,'(2f10.4)') point%x, point%y end subroutine print_2d
subroutine print_3d( point ) class(point3d) :: point
write(*,'(3f10.4)') point%x, point%y, point%z end subroutine print_3d
function add_vector_2d( point, vector ) class(point2d), intent(in)
:: point class(point2d), intent(in) :: vector type(point2d)
:: add_vector_2d
add_vector_2d%x = point%x + vector%x add_vector_2d%y = point%y
+ vector%y
end function add_vector_2d
function add_vector_3d( point, vector ) class(point3d), intent(in)
:: point type(point3d), intent(in) :: vector
type(point3d) :: add_vector_3d
add_vector_3d%point2d = point%point2d + vector%point2d
add_vector_3d%z = point%z + vector%z
end function add_vector_3d
end module points2d3d
program random_walk
use points2d3d ! Both 2D and 3D points available
type(point2d), target :: point_2d, vector_2d type(point3d),
target :: point_3d, vector_3d
! ! A variable of class point2d can point to point_2d but !
also to point_3d ! class(point2d), pointer :: point, vector
integer :: nsteps = 100 integer :: i integer
:: trial real :: deltt = 0.1
! Select what type of point ... point => point_2d vector =>
vector_2d
do trial = 1,2 if ( trial == 1 ) then
write(*,*) 'Two-dimensional walk:' else write(*,*)
'Three-dimensional walk:' endif
call random_vector( point )
do i = 1,nsteps call random_vector( vector )
point = point + vector
call print_point( point ) enddo
! Now let's take a 3D walk ...
point => point_3d vector => vector_3d
enddo
end program random_walk
_______________________________________________
J3 mailing list
J3 at j3-fortran.org
http://j3-fortran.org/mailman/listinfo/j3
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://j3-fortran.org/pipermail/j3/attachments/20110511/ebdda564/attachment.html>
More information about the J3
mailing list