- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi FortranFan, many thanks for your fast answer. Cool, it works nice. That brings my code a huge step further.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page