在FORTRAN 2003中完成 [英] Finalisation in FORTRAN 2003

查看:53
本文介绍了在FORTRAN 2003中完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 Fortran Wiki intel fortran 编译器版本14应该支持FORTRAN 2003标准中定义的完成.我尝试通过 ifort 14 使用此功能,但观察到了奇怪的行为.以下示例应显示以下内容:

According to Fortran Wiki the intel fortran compiler version 14 should support finalisation defined in FORTRAN 2003 standard. I tried to use this feature with ifort 14, but observed strange behaviour. Following example should show this:

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 打印到stdout.最后,应该使用 final 例程 delete_mytype 进行终结处理,尽管在此示例情况下,它仅将一些信息打印到stdout.

Within this complete example the type mytype is defined that only has one value nr. This type can be created using simple type constructor e.g. mytype(1) or the initialising function init_mytype. Also a subroutine print_mytype is defined that simply prints mytype%nr to stdout. Finally, the final routine delete_mytype should be used for finalisation, although in this example case it only prints some information to stdout.

此示例给出以下输出:

 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
    • Line 1: Ok, t1 initialised with default value 0
    • Line 2: Ok, t2 initialised with default value 0
    • Line 3: Ok, after assignment of new object t1%mytype(1) the old version is deleted
    • Line 4: Ok, version with nr = 1 is printed
    • Line 5: Strange, where does a version with nr=-2 come from?
    • Line 6: Ok, version with nr = 2 is initialised
    • Line 7: Ok, after assignment of new object t2 = init_mytype(2) the old version is deleted
    • Line 8: Strange, t2 is finalized before call of t2%print_mytype()
    • Line 9: Strange, t2 is printed after finalisation
    • 这种奇怪的行为是由ifort错误引起的还是由FORTRAN 2003终结功能的错误应用引起的,而我做错了吗?

      Is this strange behviour caused by some ifort bug or is this caused by wrong application of the finalization FORTRAN 2003 feature and I am doing something wrong?

      推荐答案

      看起来有些奇怪的实际上是终结规则的结果.在Fortran 2008 4.5.6.3(完成终结处理"中)中给出了完成终结处理的提示.

      What appears strange is actually the result of the rules on finalization. In Fortran 2008 4.5.6.3 ("When finalization occurs") the prompts for finalization are given.

      在介绍这些内容之前,先讲一下初始化.你说

      Before coming to those, a word about initialization. You say

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

      Line 1: Ok, t1 initialised with default value 0

      派生类型组件 nr 没有默认的初始化,并且 t1 没有显式的初始化,因此您的说法不正确.实际上,此时尚未定义 t1%nr . 0 恰好是结果.这很重要,正如我们稍后所看到的.

      The derived type component nr doesn't have default initialization, and there's no explicit initialization for t1, so your statement isn't true. In fact, t1%nr is undefined at this point. 0 just happens to be the result. This is important, as we see later.

      您的代码,其中包含有关定稿的注释:

      Your code, with comments about finalization:

      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行的意外行为并不奇怪.特别是,在语句 t2 = init_mytype(2)中的两次完成调用之后,发生 call t2%print_mytype().

      Your lines 8 and 9 unexpected behaviour are not strange. In particular, call t2%print_mytype() occurs after the two finalization calls in the statement t2=init_mytype(2).

      现在,第5行的终结来自何处?为什么是 -2 ?还记得没有初始化吗?如果未分配实体的终结处理发生,则 -2 是允许的结果.哪个实体已完成?

      Now, where does the finalization from line 5 come from? And why -2? Remember that there is no initialization? -2 is an allowed result if a finalization occurs for an entity without assignment. Which entity is finalized?

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

      Look in the function init_mytype returning a result of type 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
      

      最后,此程序中出现以下提示:

      To conclude, the following prompts occur in this program:

      • 当执行内部赋值语句时,将在评估expr之后且在定义变量之前将变量定型.
      • 如果可执行结构引用了一个函数,则在执行包含引用的最里面的可执行结构后,将最终确定结果.

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

      As an aside, if you look at the draft Fortran 2008 standard (such as I did when I mistakenly copied the wrong prompt in an earlier revision of this answer) you may think: why aren't the results of the structure constructor finalized? This should happen twice: once directly in the program, and once indirectly through the call to init_mytype. But we see no such effect.

      考虑解释请求最终确定构造值多少次?"勘误.构造函数的结果被认为尚未最终确定,从而纠正了Fortran 2003中的一个错误.这可能是相关的,因为您确实询问过Fortran 2003(尽管ifort明确实现了新规则).

      Consider the interpretation request "How many times are constructed values finalized?" and the corrigendum. Constructor results are considered to be not finalized, correcting a mistake in Fortran 2003. This may be relevant, as you do ask about Fortran 2003 (although ifort clearly implements the new rules).

      这篇关于在FORTRAN 2003中完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆