问题
I have an object parsing a textfile. Here's my main program:
program main
use Parser_class
implicit none
type(Parser) :: Parser
call Parser%ProcessFile('data.txt')
call Parser%Deallocate
end program main
where the type definition is
module Parser_class
type :: Parser
contains
procedure, public :: ProcessFile
procedure, public :: Deallocate
end type Parser
contains
subroutine ProcessFile(self)
...
end subroutine
subroutine Deallocate(self)
class(Parser) :: self
...
end subroutine
end module Parser_class
I read about the final keyword and altered the type definition to
module Parser_class
type :: Parser
contains
procedure, public :: ProcessFile
final :: Deallocate
end type Parser
contains
subroutine ProcessFile(self)
...
end subroutine
subroutine Deallocate(self)
type(Parser) :: self
...
end subroutine
end module Parser_class
Additionally, in the main program I don't have call Parser%Deallocate
anymore. The finalizer doesn't get called now at any time. I somehow get this is because I never destroy or overwrite the Parser
object. But how could I do this, or what is the proper way to handle the deallocation process?
回答1:
In the Fortran 2008 standard, when finalization comes about is given in section 4.5.6.31. I won't copy all the times here, but I will summarize.
What is clearly mentioned following from when, is when not:
If image execution is terminated, either by an error (e.g. an allocation failure) or by execution of a stop-stmt, error-stop-stmt, or end-program-stmt, entities existing immediately prior to termination are not finalized.
This covers your program. Parser
is in the program's scope and it still exists at the end of the program. There are no apparent other things which would cause finalization.
If Deallocate
is a final procedure for the type, then there are subtle ways in which finalization of an object of that type differ from a call of the type-bound procedure. In finalization, the process is recursive: components and parents are themselves subject to finalization. With a subroutine call that recursion must appear manually in some way.
In many cases one doesn't care that an entity isn't finalized at the end of the program. After all, any deallocation is then the operating system's problem, not the programmer's. However, there are times other forms of tidying up are indeed desirable.
True finalization can be forced in some ways. If the list below is examined, two options come to mind:
- make the
Parser
object allocatable and explicitly deallocate it; - wrap the whole thing in a
block
construct.
To crudely summarize when finalization happens:
- when there's deallocation (pointer or allocatable);
- as procedure start-up with
intent(out)
arguments; - when reaching the end of an executable construct or subprogram, for non-saved local objects;
- just before intrinsic assignment to a variable;
- after the value of a function's result is finished with.
1If you aren't reading the final form of the document you'll want to pretend paragraphs 5 and 7 don't exist.
来源:https://stackoverflow.com/questions/40677624/how-to-properly-finalize-an-object-in-fortran