inspired by the recent derived-type constructor issue (http://software.intel.com/en-us/forums/topic/375761), I decided to post some related example code which also behaves differently than I expected. I tested with ifort 13.0.1, and counterchecked with gfortran (gcc) 4.7.2.
EXAMPLE I: polymorphic components
- set up structure constructor for a 'container', containing an other derived-type 'child' by reference
- 'child' is polymorphic, and it's superclass may be empty
module m ! possibly empty superclass type :: super integer :: field ! add a field (or not) end type type, extends(super) :: child end type ! reference container type :: container class(super), pointer :: ptr => null() end type end module m program p use m implicit none type(child), target :: myChild type(container) :: myContainer ! initialize the container with a reference to child !-----ALTERNATIVE A-------- ! direct pointer assignment myContainer%ptr => myChild ! ifort: output "T" ! gfortran: output "T" !-----ALTERNATIVE B-------- ! structure constructor myContainer = container(myChild) ! ifort: compiler-error #6795 ! "The target must be of the same type and kind ! type parameters as the pointer [MYCHILD]" ! gfortran: compiler-error ! "Can't convert TYPE(child) to CLASS(super)" !-----ALTERNATIVE C-------- ! structure constructor wich matches the declared type class(super), pointer :: super_ptr super_ptr => myChild ! cast to superclass myContainer = container(super_ptr) ! ifort: if super has NO data fields: output "F" ! if super has at least one data field: output "T" ! gfortran: (both cases) output "T" ! check initialization, output "T" expected print *, associated(myContainer%ptr) end program
- ALTERNATIVE A: This is what I want to do with structure constructors.
- ALTERNATIVE B: The structure constructor assignment fails, even if a direct pointer assignment is allowed.
The intel reference pages told me that "If a component of the derived type is a pointer, the value in the expression list must evaluate to an object that would be a valid target in a pointer assignment statement. (A constant is not a valid target in a pointer assignment statement.)". It also sais, that "If necessary, values are converted (according to the rules of assignment), to agree with their corresponding components in type and kind parameters.", so I thought the structure construcor should workd here (but both ifort and gfortran complained)
- ALTERNATIVE C: Strangely, it seems to make a difference if the superclass "super" has fields or not. (it doesn't help here to add type-bound procedures). This problem with empty types is also adressed in EXAMPLE II
EXAMPLE II: empty derived type
- now, the containedderived-type is non-polymorphic and may be empty
module m ! empty derived type type :: empty ! integer :: field ! add a field (or not) end type ! reference container type :: container type(empty), pointer :: ptr => null() end type end module m program p use m implicit none type(empty), target :: myEmpty type(container) :: myContainer ! initialize the container with a reference to empty myContainer = container(myEmpty) ! check initialization (output "T" expected) print *, associated(myContainer%ptr) ! results: ! ifort: if super_type has NO data fields: output "F" ! if super_type has at least one data field: output "T" ! gfortran: (both cases) output "T" end program
- Now, the structure constructor works fine (no polymorphism any more), unless the "empty" type is indeed empty (that was a known issue in ifort 11, but still in 13?)
Thanks for comments and in the hope this may be useful,