Skip to content

Instantly share code, notes, and snippets.

@pelson
Last active March 15, 2019 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pelson/73710120d5e7ede9318bbf56fb52c52a to your computer and use it in GitHub Desktop.
Save pelson/73710120d5e7ede9318bbf56fb52c52a to your computer and use it in GitHub Desktop.
Demonstration of Intel Fortran compiler issue
gfortran -g main.f90 -fbacktrace -O0 && ./a.out
ifort main.f90 \
-traceback -warn interface \
-o a.intel.out && ./a.intel.out
module container_example
type containable_base_type
character(80) :: name
end type containable_base_type
type, public :: container_type
class(containable_base_type), pointer :: payload => null()
contains
final :: container_destructor
end type container_type
interface container_type
module procedure container_constructor
end interface container_type
contains
function container_constructor(child) result(self)
type(container_type) :: self
class(containable_base_type), intent (in) :: child
print*, "Construct container"
allocate(self%payload, source=child)
end function container_constructor
subroutine container_destructor(self)
type (container_type), intent(inout) :: self
print*, "Destruct container"
if (associated(self%payload)) then
! BOOM! with the intel compiler second time around.
deallocate(self%payload)
end if
end subroutine container_destructor
end module container_example
program main
use container_example
type(container_type) :: holder
holder = container_type(containable_base_type('example 1'))
print*, holder%payload%name
holder = container_type(containable_base_type('example 2'))
print*, holder%payload%name
end program main
@pelson
Copy link
Author

pelson commented Mar 15, 2019

Solution: implement assignment such as

  ...

    generic, public                              :: assignment(=) => container_assign
  end type container_type

  ...

  subroutine container_assign(self, from_container)
    class(container_type), intent(out) :: self
    class(container_type), target, intent(in) :: from_container
    allocate(self%payload, source=from_container%payload)
  end subroutine container_assign

@pelson
Copy link
Author

pelson commented Mar 15, 2019

This is essentially ifort copying pointers rather than copying the data being pointed to as its default assignment behaviour. A shared pointer concept would be reasonably easy to implement in F2003 I believe.

It seems that associated is not safe in the ifort implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment