在FORTRAN 2003中完成 [英] Finalisation in 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屋!