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

pointer to extended class object - standard conforming? -> solved

Johannes_Rieke
New Contributor III
434 Views

Hi, I tried to figure out how I can assign dynamically extended types by the use of pointers to components of an array of objects. Here is my example code:

module mytypes
  implicit none  
  public  
  ! ------------------
  type t_ELE
    integer :: linear = 0
  end type t_ELE
  
  type, extends(t_ELE) :: t_QUAD4
    integer :: nodes = 4
  end type
  
  type, extends(t_ELE) :: t_QUAD8
    integer :: nodes = 8
  end type  
  ! -------------------
  type t_element_list
    class(t_ELE), pointer :: element_type => Null()
  end type t_element_list

end module mytypes

! -------------------
program v
  use mytypes, only : t_QUAD4, t_QUAD8, t_element_list
  implicit none
  ! Variables  
  type(t_QUAD4), target             :: QUAD4
  type(t_QUAD8), target             :: QUAD8  
  type(t_element_list), allocatable :: my_element_list(:)
  
  allocate(my_element_list(73))
  
  my_element_list(1)%element_type => QUAD4 ! no error here, but is this standard conforming?
  
  ! this works
  write(*,*) my_element_list(1)%element_type%linear
  
  ! this line triggers a compile time error if uncommented:
  ! eror #6460: This is not a field name that is defined in the encompassing structure.   [NODES]
  !write(*,*) my_element_list(1)%element_type%nodes  
  
  my_element_list(1)%element_type => Null()
end program v

My first question is: Is this standard conforming?

My second question is: Why does the compiler throw (19.0.5, gfortran 9.1 too) a compile time error? This is obsolete, if the first question shows, that the code violates the (newest supported) standard.

My third question is: How could I circumvent this problem by a different design approach? Any ideas are welcome.

BR, Johannes

0 Kudos
1 Solution
FortranFan
Honored Contributor II
434 Views

@Johannes,

The answer to your first question is yes.  Re: the compiler error, you need to effectively 'cast' the relevant component to the extended type to reference it like so:

program v
   use mytypes, only : t_QUAD4, t_QUAD8, t_element_list
   implicit none
   ! Variables
   type(t_QUAD4), target             :: QUAD4
   type(t_QUAD8), target             :: QUAD8
   type(t_element_list), allocatable :: my_element_list(:)

   allocate(my_element_list(73))

   my_element_list(1)%element_type => QUAD4 ! Ok
   ! this works
   write(*,*) my_element_list(1)%element_type%linear ! Ok, linear a component of 'class(T_ELE)'

   select type ( element => my_element_list(1)%element_type )
      type is ( t_QUAD4 )
         write(*,*) element%nodes
   end select

   my_element_list(1)%element_type => Null()

end program v

 

View solution in original post

0 Kudos
2 Replies
FortranFan
Honored Contributor II
435 Views

@Johannes,

The answer to your first question is yes.  Re: the compiler error, you need to effectively 'cast' the relevant component to the extended type to reference it like so:

program v
   use mytypes, only : t_QUAD4, t_QUAD8, t_element_list
   implicit none
   ! Variables
   type(t_QUAD4), target             :: QUAD4
   type(t_QUAD8), target             :: QUAD8
   type(t_element_list), allocatable :: my_element_list(:)

   allocate(my_element_list(73))

   my_element_list(1)%element_type => QUAD4 ! Ok
   ! this works
   write(*,*) my_element_list(1)%element_type%linear ! Ok, linear a component of 'class(T_ELE)'

   select type ( element => my_element_list(1)%element_type )
      type is ( t_QUAD4 )
         write(*,*) element%nodes
   end select

   my_element_list(1)%element_type => Null()

end program v

 

0 Kudos
Johannes_Rieke
New Contributor III
434 Views

Hi FortranFan, many thanks for your fast answer. Cool, it works nice. That brings my code a huge step further.

0 Kudos
Reply