在FORTRAN 2003中完成定稿

在FORTRAN 2003中完成定稿,fortran,intel-fortran,fortran2003,Fortran,Intel Fortran,Fortran2003,根据英特尔fortran编译器版本14应支持fortran 2003标准中定义的最终版本。我试图将此功能用于ifort 14,但观察到奇怪的行为。以下示例应说明这一点: module mtypes implicit none type mytype integer, private :: nr contains final :: delete_mytype procedure :: print_m

根据英特尔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
  • 第1行:Ok,t1初始化为默认值0
  • 第2行:Ok,t2初始化为默认值0
  • 第3行:确定,在分配新对象
    t1%mytype(1)
    后,删除旧版本
  • 第4行:确定,打印的版本为
    nr=1
  • 第5行:奇怪,nr=-2的版本来自哪里
  • 第6行:确定,初始化了nr=2的版本
  • 第7行:好的,在分配新对象
    t2=init\u mytype(2)
    之后,旧版本被删除
  • 第8行:奇怪,在调用
    t2%print\u mytype()
  • 第9行:奇怪,t2在定稿后打印

这种奇怪的现象是由某些ifort bug引起的,还是由于错误地应用了finalization FORTRAN 2003功能而导致的,我做错了什么?

看起来奇怪的实际上是关于定稿的规则的结果。在Fortran 2008 4.5.6.3(“完成时”)中,给出了完成提示

在讨论这些问题之前,先谈谈初始化。你说

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

派生类型组件
nr
没有默认初始化,并且
t1
没有显式初始化,因此您的语句不正确。事实上,
t1%nr
此时未定义<代码>0恰好是结果。正如我们稍后看到的,这很重要

您的代码,以及有关完成的注释:

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行的意外行为并不奇怪。特别是,
callt2%print\u mytype()
发生在语句
t2=init\u 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\u mytype
间接发生。但我们看不到这种影响


考虑解释请求和请求。构造函数结果被认为是未最终确定的,这纠正了Fortran 2003中的一个错误。这可能与Fortran 2003有关(尽管ifort明确实现了新规则)。

在类型定义中设置一个默认值,
integer,private::nr=0
,比依赖编译器自动初始化要好。也就是说,据我所知,ifort默认将所有整数初始化为零,所以我不确定是什么导致了这些问题。在我的机器上,它在第5行打印零。在第5行可以。最后一个问题在第8行。init_mytype中nr=2的对象被复制到main中的t2,然后在init_mytype中完成。t2在main中没有最终确定,因为它是main的结尾。这种理解正确吗?有两个对象的
nr=2
,是的,它确实是
init\u mytype
最终确定的结果(另一个是赋值后的
t2
)。到达
END PROGRAM
“如果图像执行被终止,..,通过执行..END PROGRAM stmt,终止前存在的实体不会被终止。”
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