How to properly finalize an object in Fortran?

隐身守侯 提交于 2019-12-02 11:25:42

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!