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

Unlimited polymorphic variables

NsK
Novice
608 Views

Hello,

I'm really afraid of reporting this one...

Please tell me it is standard, and if it's not, that the standard is going to change:

module dummy_module
    implicit none
        
    type :: a_type
        integer(4) :: val
    end type a_type
        
    type :: b_type
        integer(4) :: val1 
        integer(4) :: val2
    end type b_type
        
contains
    
    function f(x)
    ! Variables
        class(*), target  :: x
        class(*), pointer :: f
    ! Body of f
        f => x
    end function f
        
end module dummy_module
        
    
program polymorphism_test
    use dummy_module
    implicit none

    type(a_type), pointer :: a
    type(b_type), pointer :: b     
    allocate(b)
    b%val1 = 3.0
    b%val2 = 4.0
        
    a => f(b)
    
end program polymorphism_test

 

Compiles with  XE 2013 SP1 14.0.0100.12 and  XE 2015 15.0.0107.2010 (and I think with Update 1 as well), which is perfect, but gfortran complains:

main.f90:38.8:

        a => f(b)
        1
Error: Data-pointer-object &L must be unlimited polymorphic, a sequence derived type or of a type with the BIND attribute assignment at (1) to be compatible with an unlimited polymorphic target

 

Edit:

I've just found this, it looks like it has not been resolved yet. I second antony on that, what a pity, 1000s of lines to rewrite, entire code broken... Is there any workaround to avoid using SELECT TYPE everywhere?

0 Kudos
7 Replies
FortranFan
Honored Contributor II
608 Views

NsK wrote:

..

Please tell me it is standard, and if it's not, that the standard is going to change:

...

Non-standard in my opinion; I think gfortran is correct.  Plus I don't think the standard will change in this regard and nor should it.  Fortran standard, at least philosophically (or perhaps  more eagerly than that), wishes to "protect" its practitioners from shooting themselves in the foot or worse yet, hang themselves - such a "nice" sentiment can continue!

0 Kudos
NsK
Novice
608 Views

Ok, tell me if I understand correctly: if I make a list of 100 objects, each potentially of a different class, and return a pointer to one object, I will have to write 100 lines of CLASS IS?

0 Kudos
FortranFan
Honored Contributor II
608 Views

NsK wrote:

Ok, tell me if I understand correctly: if I make a list of 100 objects, each potentially of a different class, and return a pointer to one object, I will have to write 100 lines of CLASS IS?

Not necessarily.  You will have to determine the best design pattern based on your needs and you may have to create a "container" class that holds and works with the list of objects.  You may have seen the list example in Modern Fortran Explained - Michael Metcalf, John Reid and Malcolm Cohen, Oxford University Press, 2011, ISBN 978-0199601417 which is one such option.  See a related discussion on that example here: https://software.intel.com/en-us/forums/topic/518263

0 Kudos
FortranFan
Honored Contributor II
608 Views

Separately, you may want to think further about what all you're trying to do.  For example, something like this cannot work:

program polymorphism_test
    use dummy_module
    implicit none

    type(a_type), pointer :: a
    type(b_type), pointer :: b     
    allocate(b)
    b%val1 = 3.0
    b%val2 = 4.0
        
    a => b  !.. this cannot work, a_type and b_type are "different"
    
end program polymorphism_test

so how do you expect your f procedure to "magically" make it function?

0 Kudos
NsK
Novice
608 Views

Thanks FortranFan,

I was not aware of John Reid's example, my list implementation looks quite similar actually, this "bug" just allows me to cast the content of the polymorphic container directly and remove the need for calls to type-bound procedures to access/modify the data after.

FortranFan wrote:

Separately, you may want to think further about what all you're trying to do.  For example, something like this cannot work:

program polymorphism_test
    use dummy_module
    implicit none

    type(a_type), pointer :: a
    type(b_type), pointer :: b     
    allocate(b)
    b%val1 = 3.0
    b%val2 = 4.0
        
    a => b  !.. this cannot work, a_type and b_type are "different"
    
end program polymorphism_test

so how do you expect your f procedure to "magically" make it function?

I don't expect your last example to compile, but I hoped my version would compile and crash, at runtime.

Indeed, it shifts the responsibility from the compiler to the developer.

0 Kudos
Steven_L_Intel1
Employee
608 Views

Missing error escalated as issue DPD200253728.

0 Kudos
Steven_L_Intel1
Employee
608 Views

This should be fixed in 16.0.

0 Kudos
Reply