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

In an intrinsic assignment statement, variable shall not be polymorphic.

Trent_Hawkins
Novice
796 Views

Greetings. I am facing a challenge trying to do generic programming with Fortran (templates), and searching the web I have decided that the most elegant solution is to use data polymorphism. However it seems that there is not much I can do with polymorphic objects, an more specifically assign values to them in a select type construct, where their dynamic type is checked. Example follows.

What I am trying to simulate is a tensor template as a data container of specific rank and shape, but arbitrary content type to make it reusable in many ways:

#     ifndef tensor_F90
#     define tensor_F90

      module tensor

            use precision

            implicit none

            type tensor_
               integer         ,                         public::rank
               integer         ,dimension(:),allocatable,public::shape
               integer         ,                         public::size
               class  (      *),dimension(:),allocatable,public::component
            contains
               procedure,public::tensor_initialize
        end type tensor_

      contains

            subroutine tensor_initialize(this,shape,component_sample)

                  implicit none

                  class  (tensor_),             intent(  out)::this
                  integer         ,dimension(:),intent(in   )::shape
                  class  (      *),             intent(in   )::component_sample ! this is to define the type of the components only

                  this%rank=size(shape)
                  allocate(this%shape(this%rank))
                  this%shape=shape
                  this%size=product(this%shape)
                  allocate(this%component(this%size),source=component_sample)

                  select type(component_sample)
                  type is(complex)
                     this%component=(1.,0.)
              end select

        end subroutine tensor_initialize

  end module tensor
  
#     endif

What I am getting from ifort (2016 - update 3) is:

tensor.F90(37): error #8304: In an intrinsic assignment statement, variable shall not be polymorphic.   [COMPONENT]
                     this%component=(1.,0.)
--------------------------^

I have also tried several other way to access the polymorphic component object list with no gain, and always the same message. The restriction message makes sense, as a polymorphic object is an unknown unless you give it... "shape", which I thought happens in a select type construct where the specifics of a polymorphic type are constraint. I realize that the problem may arise from the language specification forbidding the intrinsic types to interact with derived ones (for example allow extension of intrinsic types to derived ones), however I fail to make assignments even between derived type objects, and the select type construct having no effect whatsoever.

I would be grateful for any advice on the matter as I would hate to migrate to C++ for simulation stuff. To be honest, any advice on alternatives to generic programming in Fortran (I am aware of Parametric Fortran) would be more than welcome. Thank you in advance for your time.

 

Trent

0 Kudos
1 Solution
Steven_L_Intel1
Employee
796 Views

You almost had it. The issue is that the SELECT TYPE has to name the thing you want to assign to, not some arbitrary other variable. This is what you want there:

                  select type(component=>this%component)
                  type is(complex)
                     component=(1.,0.)
              end select

Intrinsic assignment to a polymorphic variable is a Fortran 2008 feature not yet implemented in Intel Fortran. It should be there a year from now.

View solution in original post

0 Kudos
2 Replies
Steven_L_Intel1
Employee
797 Views

You almost had it. The issue is that the SELECT TYPE has to name the thing you want to assign to, not some arbitrary other variable. This is what you want there:

                  select type(component=>this%component)
                  type is(complex)
                     component=(1.,0.)
              end select

Intrinsic assignment to a polymorphic variable is a Fortran 2008 feature not yet implemented in Intel Fortran. It should be there a year from now.

0 Kudos
Trent_Hawkins
Novice
796 Views

Sincere thanks Steve! After trying what you said and still getting the same compiler error, I also realized that the reason the compiler insists the object is polymorphic is because I constrain the type with class is, and not type is, in which case indeed the object is still polymorphic and not type-specific.

0 Kudos
Reply