在 FORTRAN 2003 中完成
Finalisation in FORTRAN 2003
根据 Fortran Wiki,intel 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是finalisation后打印出来的
这种奇怪的行为是由某些 ifort 错误引起的,还是由于错误应用了最终化 FORTRAN 2003 功能而我做错了什么?
看似奇怪的,其实是敲定规则的结果。在 Fortran 2008 4.5.6.3 ("When finalization occurs") 中给出了完成的提示。
在谈到这些之前,先说说初始化。你说
Line 1: Ok, t1 initialised with default value 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 行的意外行为并不奇怪。特别是,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
综上所述,本程序出现如下提示:
- When an intrinsic assignment statement is executed, the variable is finalized after evaluation of expr and before the definition of the variable.
- If an executable construct references a function, the result is finalized after execution of the innermost executable construct containing the reference.
顺便说一句,如果您查看 Fortran 2008 标准草案(例如我在该答案的早期修订版中错误地复制了错误的提示时所做的),您可能会想:为什么结果不是结构构造函数完成了吗?这应该发生两次:一次直接在程序中发生,一次通过调用 init_mytype
间接发生。但是我们没有看到这样的效果。
考虑解释请求 "How many times are constructed values finalized?" and the corrigendum。构造函数结果被认为是未最终确定的,更正了 Fortran 2003 中的错误。这可能是相关的,因为您确实询问了 Fortran 2003(尽管 ifort 明确实施了新规则)。
根据 Fortran Wiki,intel 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是finalisation后打印出来的
这种奇怪的行为是由某些 ifort 错误引起的,还是由于错误应用了最终化 FORTRAN 2003 功能而我做错了什么?
看似奇怪的,其实是敲定规则的结果。在 Fortran 2008 4.5.6.3 ("When finalization occurs") 中给出了完成的提示。
在谈到这些之前,先说说初始化。你说
Line 1: Ok, t1 initialised with default value 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 行的意外行为并不奇怪。特别是,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
综上所述,本程序出现如下提示:
- When an intrinsic assignment statement is executed, the variable is finalized after evaluation of expr and before the definition of the variable.
- If an executable construct references a function, the result is finalized after execution of the innermost executable construct containing the reference.
顺便说一句,如果您查看 Fortran 2008 标准草案(例如我在该答案的早期修订版中错误地复制了错误的提示时所做的),您可能会想:为什么结果不是结构构造函数完成了吗?这应该发生两次:一次直接在程序中发生,一次通过调用 init_mytype
间接发生。但是我们没有看到这样的效果。
考虑解释请求 "How many times are constructed values finalized?" and the corrigendum。构造函数结果被认为是未最终确定的,更正了 Fortran 2003 中的错误。这可能是相关的,因为您确实询问了 Fortran 2003(尽管 ifort 明确实施了新规则)。