- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I've encountered a compiler bug when using an array of derived-type with an polymorphic component.
I'm using ifort version 13.1.1.
There is the code which produce the error:
[fortran]Module MyModule
implicit none
private
public :: MyType
Type ,abstract :: Object
End Type
Type :: MyType
integer :: Num
class(Object) ,allocatable :: Data
End Type
Interface MyType
Module Procedure Construct_MyType
End Interface
contains
Function Construct_MyType( Num ) result(This)
implicit none
type(MyType) :: This
integer ,optional ,intent(in) :: Num
This%Num = 1
if ( present(Num) ) This%Num = Num
End Function
End Module
Program Main
use MyModule ,only: MyType
implicit none
type(MyType) ,dimension(:) ,allocatable :: Vars
type(MyType) :: Var1, Var2
integer :: iVar
write(*,"(/,'[Main]: Method 1:')")
Var1 = MyType( Num = 1 ) ! Var1 has the correct value for the "Num" component
Var2 = MyType( Num = 2 ) ! Var2 has the correct value for the "Num" component
write(*,"('[Main]: Var1%Num = ',i3)") Var1%Num
write(*,"('[Main]: Var2%Num = ',i3)") Var2%Num
write(*,"(/,'[Main]: Method 2:')")
allocate( Vars(2) )
Vars(1) = MyType( Num = 1 ) ! Vars(1) has the correct value for the "Num" component
write(*,"('[Main]: Vars(1)%Num = ',i3)") Vars(1)%Num
Vars(2) = MyType( Num = 2 )
write(*,"('[Main]: Vars(2)%Num = ',i3)") Vars(2)%Num ! Vars(2) has the correct value for the "Num" component BUT VALUE IN VARS(1) HAS BEEN CHANGED !!!
write(*,"('[Main]: Vars(1)%Num = ',i3)") Vars(1)%Num
write(*,"('[Main]: Vars(2)%Num = ',i3)") Vars(2)%Num
! write(*,"(/,'[Main]: Method 3:')") ! Same results than with method 2, ie erroneous
! Vars(1) = Var1
! write(*,"('[Main]: Vars(1)%Num = ',i3)") Vars(1)%Num
! Vars(2) = Var2
! write(*,"('[Main]: Vars(2)%Num = ',i3)") Vars(2)%Num
! write(*,"('[Main]: Vars(1)%Num = ',i3)") Vars(1)%Num
! write(*,"('[Main]: Vars(2)%Num = ',i3)") Vars(2)%Num
End Program
[/fortran]
the output of the code is:
[Main]: Method 1:
[Main]: Var1%Num = 1
[Main]: Var2%Num = 2
[Main]: Method 2:
[Main]: Vars(1)%Num = 1
[Main]: Vars(2)%Num = 2
[Main]: Vars(1)%Num = 2
[Main]: Vars(2)%Num = 2
As one can see, in Method 2, Vars(1)%Num be equal to 1 which is not the case.
Insead, it has the value of the last element of the array Vars which has been affected.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is more info on this issue.
I've tried to:
- to use an automatic array vs an allocatable arrays
- to use a subroutine vs a function constructor
The source code is:
[fortran]
Module MyModule
implicit none
private
public :: MyType
public :: Construct_MyType_Fun
public :: Construct_MyType_Sub
Type ,abstract :: Object
End Type
Type :: MyType
integer :: Num
class(Object) ,allocatable :: Data
End Type
Interface MyType
Module Procedure Construct_MyType_Fun
End Interface
contains
Function Construct_MyType_Fun( Num ) result(This)
implicit none
type(MyType) :: This
integer ,optional ,intent(in) :: Num
This%Num = 1
if ( present(Num) ) This%Num = Num
End Function
Subroutine Construct_MyType_Sub( This, Num )
implicit none
type(MyType) ,intent(out) :: This
integer ,optional ,intent(in) :: Num
This%Num = 1
if ( present(Num) ) This%Num = Num
End Subroutine
End Module
Program Main
use MyModule ,only: MyType, Construct_MyType_Fun, Construct_MyType_Sub
implicit none
type(MyType) ,dimension(2) :: Vars_Auto
type(MyType) ,dimension(:) ,allocatable :: Vars_Allo
allocate( Vars_Allo(2) )
write(*,"('[Main]: size(Vars_Auto) = ',i0)") size(Vars_Auto)
write(*,"('[Main]: size(Vars_Allo) = ',i0)") size(Vars_Allo)
write(*,"(/,'[Main]: Constructing Vars_Allo using Construct_MyType_Sub:')")
call Construct_MyType_Sub( Vars_Allo(1), Num = 1 )
write(*,"('[Main]: Vars_Allo(1)%Num = ',i3)") Vars_Allo(1)%Num
call Construct_MyType_Sub( Vars_Allo(2), Num = 2 )
write(*,"('[Main]: Vars_Allo(2)%Num = ',i3)") Vars_Allo(2)%Num
write(*,"('[Main]: Vars_Allo(1)%Num = ',i3)") Vars_Allo(1)%Num
write(*,"('[Main]: Vars_Allo(2)%Num = ',i3)") Vars_Allo(2)%Num
write(*,"(/,'[Main]: Constructing Vars_Auto using Construct_MyType_Sub:')")
call Construct_MyType_Sub( Vars_Auto(1), Num = 1 )
write(*,"('[Main]: Vars_Auto(1)%Num = ',i3)") Vars_Auto(1)%Num
call Construct_MyType_Sub( Vars_Auto(2), Num = 2 )
write(*,"('[Main]: Vars_Auto(2)%Num = ',i3)") Vars_Auto(2)%Num
write(*,"('[Main]: Vars_Auto(1)%Num = ',i3)") Vars_Auto(1)%Num
write(*,"('[Main]: Vars_Auto(2)%Num = ',i3)") Vars_Auto(2)%Num
write(*,"(/,'[Main]: Constructing Vars_Allo using Construct_MyType_Fun:')")
Vars_Allo(1) = Construct_MyType_Fun( Num = 1 )
write(*,"('[Main]: Vars_Allo(1)%Num = ',i3)") Vars_Allo(1)%Num
Vars_Allo(2) = Construct_MyType_Fun( Num = 2 )
write(*,"('[Main]: Vars_Allo(2)%Num = ',i3)") Vars_Allo(2)%Num
write(*,"('[Main]: Vars_Allo(1)%Num = ',i3)") Vars_Allo(1)%Num
write(*,"('[Main]: Vars_Allo(2)%Num = ',i3)") Vars_Allo(2)%Num
write(*,"(/,'[Main]: Constructing Vars_Auto using Construct_MyType_Fun:')")
Vars_Auto(1) = Construct_MyType_Fun( Num = 1 ) ! SIGSEGV, segmentation fault occurred
write(*,"('[Main]: Vars_Auto(1)%Num = ',i3)") Vars_Auto(1)%Num
Vars_Auto(2) = Construct_MyType_Fun( Num = 2 )
write(*,"('[Main]: Vars_Auto(2)%Num = ',i3)") Vars_Auto(2)%Num
write(*,"('[Main]: Vars_Auto(1)%Num = ',i3)") Vars_Auto(1)%Num
write(*,"('[Main]: Vars_Auto(2)%Num = ',i3)") Vars_Auto(2)%Num
End Program
[/fortran]
and the output is
ifort main.f90 ; ./a.out
[Main]: size(Vars_Auto) = 2
[Main]: size(Vars_Allo) = 2
[Main]: Constructing Vars_Allo using Construct_MyType_Sub:
[Main]: Vars_Allo(1)%Num = 1
[Main]: Vars_Allo(2)%Num = 2
[Main]: Vars_Allo(1)%Num = 1
[Main]: Vars_Allo(2)%Num = 2
[Main]: Constructing Vars_Auto using Construct_MyType_Sub:
[Main]: Vars_Auto(1)%Num = 1
[Main]: Vars_Auto(2)%Num = 2
[Main]: Vars_Auto(1)%Num = 1
[Main]: Vars_Auto(2)%Num = 2
[Main]: Constructing Vars_Allo using Construct_MyType_Fun:
[Main]: Vars_Allo(1)%Num = 1
[Main]: Vars_Allo(2)%Num = 2
[Main]: Vars_Allo(1)%Num = 2
[Main]: Vars_Allo(2)%Num = 2
[Main]: Constructing Vars_Auto using Construct_MyType_Fun:
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image PC Routine Line Source
a.out 000000000040555F Unknown Unknown Unknown
a.out 0000000000405499 Unknown Unknown Unknown
a.out 0000000000405175 Unknown Unknown Unknown
a.out 00000000004036C9 Unknown Unknown Unknown
a.out 0000000000402B1C Unknown Unknown Unknown
libc.so.6 000000310F621735 Unknown Unknown Unknown
a.out 00000000004029F9 Unknown Unknown Unknown
The subroutine constructor constructs the derived-type with a correct value for both the automatic and allocatable cases.
The function constructor constructs the derived-type with an erroneous value for the allocatable case and fails to construct the derived-type in the automatic case (segmentation fault).
So, a temporary work-around would be to use subroutine constructors.
Hope it help.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I believe this is the same problem reported in http://software.intel.com/en-us/forums/topic/388577 and it is escalated as issue DPD200243378. The problem is triggered by a polymorphic component of the derived type - if it is non-polymorphic, you don't get this problem. With it, it assigns to the whole array even though you asked for a single element.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This got fixed in 14.0.

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