- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Both of these problems are fixed in a release later this year.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I agree that the structure constructor here should be allowed. I have escalated this as issue DPD200248768.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page