【问题标题】:Finalisation in FORTRAN 2003在 FORTRAN 2003 中完成
【发布时间】:2015-03-13 10:58:22
【问题描述】:

根据Fortran Wikiintel fortran 编译器版本 14 应支持 FORTRAN 2003 标准中定义的终结。我尝试将此功能与 ifort 14 一起使用,但观察到了奇怪的行为。以下示例应显示:

module mtypes
    implicit none

    type mytype
        integer, private :: nr
        contains

            final :: delete_mytype
            procedure :: print_mytype
    end type

    contains


!>      \brief Constructs a new mytype
!!      \return The created mytype
!>
        function init_mytype(number)
            type(mytype) :: init_mytype
            integer, intent(in) :: number
!            allocate(init_mytype)
            init_mytype = mytype(number)
            print *, 'init mytype', number
        end function

!>      \brief De-constructs a mytype object
!>
        subroutine delete_mytype(this)
            type(mytype) :: this   !< The mytype object that will be finalized
            print *, 'Deleted mytype!', this%nr
        end subroutine delete_mytype

!>      \brief Print something from mytype object
!>
        subroutine print_mytype(this)
            class(mytype) :: this   !< The mytype object that will print something
            print *, 'Print something from mytype!', this%nr
        end subroutine print_mytype


end module mtypes

program main

    use mtypes
    type(mytype) :: t1, t2

    call t1%print_mytype()
    call t2%print_mytype()

    t1 = mytype(1)
    call t1%print_mytype()
    t2 = init_mytype(2)
    call t2%print_mytype()

end program main

在这个完整的例子中,type mytype 被定义为只有一个值nr。这种类型可以使用简单的类型构造函数来创建,例如mytype(1) 或初始化函数init_mytype。还定义了一个子例程print_mytype,它简单地将mytype%nr 打印到标准输出。最后,final 例程 delete_mytype 应该用于最终确定,尽管在本例中它只将一些信息打印到标准输出。

此示例给出以下输出:

 Print something from mytype!           0
 Print something from mytype!           0
 Deleted mytype!           0
 Print something from mytype!           1
 Deleted mytype!          -2
 init mytype           2
 Deleted mytype!           0
 Deleted mytype!           2
 Print something from mytype!           2
  • 第 1 行:好的,t1 初始化为默认值 0
  • 第 2 行:好的,t2 初始化为默认值 0
  • 第 3 行:好的,分配新对象t1%mytype(1) 后,旧版本被删除
  • 第 4 行:好的,带有 nr = 1 的版本已打印
  • 第 5 行:奇怪,nr=-2 的版本是从哪里来的?
  • 第 6 行:好的,带有nr = 2 的版本已初始化
  • 第 7 行:好的,分配新对象 t2 = init_mytype(2) 后,旧版本被删除
  • 第 8 行:奇怪,t2 在调用 t2%print_mytype() 之前完成
  • 第 9 行:奇怪,t2 在定稿后打印

这种奇怪的行为是由某些 ifort 错误引起的,还是由于错误应用了终结 FORTRAN 2003 功能而我做错了什么?

【问题讨论】:

  • 最好在类型定义中设置一个默认值integer, private :: nr = 0,而不是依赖编译器完成的自动初始化。话虽如此,据我所知,ifort 默认将所有整数初始化为零,所以我不确定是什么导致了这些问题。在我的机器上,它在第 5 行打印零。

标签: fortran intel-fortran fortran2003


【解决方案1】:

看起来奇怪的其实是定稿规则的结果。在 Fortran 2008 4.5.6.3(“发生终结时”)中,给出了终结提示。

在谈到这些之前,先谈谈初始​​化。你说

第 1 行:好的,t1 初始化为默认值 0

派生类型组件nr 没有默认初始化,t1 也没有显式初始化,所以你的说法不正确。事实上,t1%nr 在这一点上是未定义的。 0 恰好是结果。这很重要,我们稍后会看到。

你的代码,带有关于终结的 cmets:

t1 = mytype(1)          ! t1 finalized before assignment
call t1%print_mytype()
t2 = init_mytype(2)     ! t2 finalized before assignment, after function
                        ! init_mytype result finalized after assignment
call t2%print_mytype()
                        ! No finalization before END PROGRAM (4.5.6.4)

第 8 行和第 9 行的意外行为并不奇怪。特别是,call t2%print_mytype() 出现在语句 t2=init_mytype(2) 中的两个终结调用之后。

现在,第 5 行的最终确定来自哪里?为什么-2?还记得没有初始化吗? -2 是一个允许的结果,如果一个没有分配的实体发生最终确定。最终确定了哪个实体?

查看函数init_mytype返回mytype类型的结果:

function init_mytype(number)
  type(mytype) :: init_mytype    ! No initialization of result
  integer, intent(in) :: number

  init_mytype = mytype(number)   ! Result finalized before assignment
  print *, 'init mytype', number
end function

综上,本程序出现如下提示:

  • 执行内部赋值语句时,变量在 expr 求值之后和变量定义之前完成。
  • 如果一个可执行结构引用了一个函数,则在执行包含该引用的最里面的可执行结构后最终确定结果。

顺便说一句,如果您查看 Fortran 2008 标准草案(例如我在此答案的早期版本中错误地复制了错误提示时所做的),您可能会想:为什么不是结构构造函数的结果最终确定?这应该发生两次:一次直接在程序中,一次间接通过调用init_mytype。但我们没有看到这样的效果。

考虑解释请求"How many times are constructed values finalized?"corrigendum。构造函数结果被认为尚未最终确定,纠正了 Fortran 2003 中的一个错误。这可能是相关的,因为您确实询问了 Fortran 2003(尽管 ifort 明确实施了新规则)。

【讨论】:

  • OK 在第 5 行。最后一个问题在第 8 行。init_mytype 中 nr = 2 的对象被复制到 main 中的 t2,然后在 init_mytype 中完成。 main 中的 t2 没有最终确定,因为它是 main 的结尾。这种理解正确吗?
  • nr=2有两个对象,是的,确实是init_mytype最终确定的结果(另一个是t2赋值后的结果)。到达END PROGRAM 时没有任何最终确定。
  • “如果图像执行被终止,..,通过执行 .. end-program-stmt ,在终止之前存在的实体不会最终确定。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-28
  • 1970-01-01
  • 1970-01-01
  • 2013-02-22
  • 2013-11-19
  • 2020-01-03
相关资源
最近更新 更多