fortran66のブログ

fortran について書きます。

【メモ帳】Intel fortran v19.1 の派生型オブジェクトの代入

派生型オブジェクトの代入時の再割り付けに関する理解しがたい振る舞い

intel fortran 19.0/19.1

終了処理を伴う派生型変数を静的なスカラー変数に対して代入するとき、静的変数が reallocate されている感じ。[追記:loc関数で番地を見ると変化していないので reallocate ではなかったです。] gfortran ではそうならない。

なお unallocated な allocatble 変数に代入する時は final 処理はされない。

ソース・プログラム

module m_test
    implicit none
    type :: t_base
        integer :: i = 0
    contains
        final :: fin_base
    end type t_base
    
    contains
    
    subroutine fin_base(this)
        type(t_base), intent(in out) :: this
        print *, 'final'
    end subroutine fin_base
end module m_test
    
program test
    use m_test
    implicit none
    type(t_base) :: a
    a = a
end program test

実行結果

a=a の所で final subroutine が呼ばれている。 a=t_base() でも同様。

 final

参考

ソース・プログラム

module m_test
    implicit none
    type :: t_base
        integer :: i = 0
    contains
        final :: fin_base
    end type t_base
    
    contains
    
    subroutine fin_base(this)
        type(t_base), intent(in out) :: this
        print *, 'final'
    end subroutine fin_base
end module m_test
    
program test
    use m_test
    implicit none
    type(t_base) :: a
    type(t_base), allocatable :: b
    class(t_base), allocatable :: c
    print *, 'start'
    a = t_base()
    print *, 'end: a'
    b = a
    print *, 'end: b'
    c = a
    print *, 'end: c'
end program test

実行結果

 start
 final
 end: a
 end: b
 end: c

追記

配列の時や部分配列の時は finalization は行われませんが、配列の要素の時は finalization が行われます。スカラーの時だけ異常な振る舞いがなされるようです。

ソース・プログラム

module m_test
    implicit none
    type :: t_base
        integer :: i = 0
    contains
        final :: fin_base
    end type t_base
    
    contains
    
    subroutine fin_base(this)
        type(t_base), intent(in out) :: this
        print *, 'final'
    end subroutine fin_base
end module m_test
    
program test
    use m_test
    implicit none
    type(t_base) :: a, b(10)
    print *, 'loc a', loc(a)
    a = a
    print *, 'loc a', loc(a)
    print *, 'loc b', loc(b)
    b = b
    print *, 'loc b', loc(b)
    b(1:1) = b(1:1)
    print *, 'loc b', loc(b)
    b(1) = b(1)
    print *, 'loc b', loc(b)
    
end program test

実行結果

loc a    14000912
final
loc a    14000912
loc b    14000872
loc b    14000872
loc b    14000872
final
loc b    14000872

Fortran 2018 with Parallel Programming

Fortran 2018 with Parallel Programming

  • 作者:Ray, Subrata
  • 発売日: 2019/08/27
  • メディア: ハードカバー

Fortran ハンドブック

Fortran ハンドブック

数値計算のためのFortran90/95プログラミング入門(第2版)

数値計算のためのFortran90/95プログラミング入門(第2版)

  • 作者:牛島 省
  • 発売日: 2020/01/28
  • メディア: 単行本(ソフトカバー)