Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29396 Discussions

Problem using polymorphism in fortran 2003

wolfpackNC
Beginner
1,159 Views
Hi I don't know if I am doing something wrong or if it's the compiler. I am trying to create a generic linked list implementation. The generic record type will be extended, i.e. store different data and sort on different variables. The extended record types will inherit the sorting and link_insert / link remove method from the parent class. I have tried to boil this down to a simple example. 2 mod files and a driver. The error I get at compile time is
"
ifort -O -c ll_mod.f90
ifort -O -c ll2_mod.f90
ifort -O -c driver.f90
driver.f90(14): error #6633: The type of the actual argument differs from the type of the dummy argument. [NEWITEM]
call printPriority(newItem)
-------------------^
driver.f90(14): error #6691: A pointer dummy argument may only be argument associated with a pointer. [NEWITEM]
call printPriority(newItem)
-------------------^
driver.f90(7): error #8223: An entity declared with the CLASS keyword shall be a dummy argument or have the ALLOCATABLE or POINTER attribute. [NEWITEM]
class(recordx), target :: newItem
--------------------------^
compilation aborted for driver.f90 (code 1)
make: *** [driver.o] Error 1

"

here is the code :
[fortran]module ll_mod

   implicit none
    
    public :: printPriority

   type :: record_generic
      class ( record_generic ), pointer :: previous => null()
      class ( record_generic ), pointer :: next => null()
      integer,public :: p = 0
      contains
        procedure,public :: priority => priority_generic
   end type record_generic

    contains 
    function priority_generic(this) result(i)
        class(record_generic) :: this
        integer :: i
        i=this%p
    end function priority_generic

   subroutine printPriority(item)
        class(record_generic), pointer :: item
        write(*,*)item%priority()
   end subroutine printPriority

end module ll_mod

module ll2_mod

use ll_mod

implicit none

   type, extends(record_generic) :: recordx
      real,public :: x = 1234.5678
      contains
        procedure,public :: priority => priorityx
   end type recordx

    contains 

    function priorityx(this) result(p)
        class(recordx)  :: this
        real :: p
        p=this%x
    end function priorityx

end module


program driver

use ll2_mod


class(recordx), pointer :: linked_list => null()
class(recordx), pointer :: newItem => null()

allocate(linked_list)
allocate(newItem)



call printPriority(newItem)

deallocate(linked_list,newItem)
end program driver
[/fortran]
0 Kudos
1 Reply
reinhold-bader
New Contributor II
1,159 Views
Hello,

I see two problems with your code: The first one indeed is the error #6633 pointed out by the compiler. The reason for this is that your dummy argument has the POINTER attribute. In this case the actual argument must have the same declared type as the dummy. The reason for this is that it would otherwise be possible to dynamically change the type of the entity inside your procedure to something not type compatible with the actual argument. You can fix this in your client code by declaring

class(record_generic), pointer :: newItem => null()

and performing typed allocation

allocate(recordx :: newItem)

The second problem is that your overriding TBP priorityx does not have the same interface (excepting the passed argument dummy) as the overridden one; the function value must be an integer. So you probably will need to redesign this functionality altogether (the present ifort release might not support all F2003 stuff you need).

Regards
Reinhold
0 Kudos
Reply