问题
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
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.
This example gives following output:
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
- 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
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?
回答1:
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
Line 1: Ok, t1 initialised with default value 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)
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)
.
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?
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:
- 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.
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.
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).
来源:https://stackoverflow.com/questions/29030497/finalisation-in-fortran-2003