structure constructors: further problems

structure constructors: further problems

Аватар пользователя Ferdinand T.

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

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

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

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

7 сообщений / 0 новое
Последнее сообщение
Пожалуйста, обратитесь к странице Уведомление об оптимизации для более подробной информации относительно производительности и оптимизации в программных продуктах компании Intel.
Аватар пользователя Steve Lionel (Intel)

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

Steve
Аватар пользователя Ferdinand T.

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

Аватар пользователя Ferdinand T.

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

Аватар пользователя Steve Lionel (Intel)

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

Steve
Аватар пользователя Ferdinand T.

Цитата:

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:

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

Thanks,

Ferdinand

Аватар пользователя Steve Lionel (Intel)

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.

Steve

Зарегистрируйтесь, чтобы оставить комментарий.