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

structure constructors: further problems

Ferdinand_T_
New Contributor II
763 Views

Hello,

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

[fortran]

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

[/fortran]

Remarks:

  • 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)
    http://software.intel.com/sites/products/documentation/doclib/stdxe/2013/composerxe/compiler/fortran-mac/GUID-6521CC96-2A0E-4CE0-8036-3238F7476C34.htm
  • 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

[fortran]

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

[/fortran]

Remarks:

  • 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,

Ferdinand

0 Kudos
6 Replies
Steven_L_Intel1
Employee
763 Views

Both of these problems are fixed in a release later this year.

0 Kudos
Ferdinand_T_
New Contributor II
763 Views

Glad to hear that!

The second problem is not related to structure constructors, as association of pointers to empty types seems to be a more general issue.

Regards, Ferdinand

0 Kudos
Ferdinand_T_
New Contributor II
763 Views

Hello Steve,

a quick check with the latest ifort 2013 sp1 (version 14.0.0) solved almost all of my fortran 2003 problems!
However, with the exception of EXAMPLE I ALTERNATIVE B, where the upcasting in the structure constructor still fails with the same error message. Of course this is only a minor issue, but since I started to clear my code from all those 'pre-14.0 release workarounds', I just wondered about this one.

Thank you, with best regards
Ferdinand

0 Kudos
Steven_L_Intel1
Employee
763 Views

I agree that the structure constructor here should be allowed. I have escalated this as issue DPD200248768.

0 Kudos
Ferdinand_T_
New Contributor II
763 Views

Ferdinand T. wrote:

The second problem is not related to structure constructors, as association of pointers to empty types seems to be a more general issue.
 

Just noticed that version 14.0.1 doesn't support empty derived types completely yet, is that true?
(didn't find it in the release notes)

Example:

[fortran]

type :: empty_type

    !integer :: nonempty          ! uncomment to get expected behaviour

end type

 

type(empty_type) :: rhs

type(empty_type), allocatable :: dynamic_lhs

 

! works but should'nt:

dynamic_lhs = empty_type()

print *, allocated(dynamic_lhs)   ! output 'F'

 

! fails but shouldn't:

allocate(dynamic_lhs)

rhs = dynamic_lhs                 ! output: segm. fault

end

[/fortran]

Thanks,

Ferdinand

0 Kudos
Steven_L_Intel1
Employee
763 Views

We believe we support empty types completely. I do recall a known issue with ASSOCIATED for an allocated empty type - I'll check on its status tomorrow. It's probably connected with the second allocate succeeding when it shouldn't. FWIW, you need to compile this source with -standard-semantics to get dynamic_lhs allocated on the assignment.

0 Kudos
Reply