Finalization
| Final subroutines | |
| When final runs | |
| Finalize allocatables | |
| Design for cleanup |
Final subroutines
A final subroutine is a cleanup routine that the compiler calls on its own when a value of the type is destroyed.
Register it with the final keyword inside the contains block of the type, and give it one argument of that type.
The buffer type below registers a cleanup routine next to its data.
module buffers
implicit none
type :: buffer
integer, allocatable :: data(:)
contains
final :: cleanup
end type buffer
contains
subroutine cleanup(self)
type(buffer), intent(inout) :: self
print *, "cleanup runs"
end subroutine cleanup
end module buffers
When final runs
Finalization runs when a local variable goes out of scope, when an allocatable object is deallocated, and for temporaries the compiler creates.
It does not run for pointers being nullified, since the target may still be alive through other pointers.
The program below shows the simple case: the message appears as the block ends and the buffer is destroyed.
program demo
implicit none
use buffers
block
type(buffer) :: b
allocate(b%data(4))
print *, "inside block"
end block
print *, "after block"
end program demo
Finalize allocatables
Allocatable components are released on their own, so a final routine is only needed for extra work such as closing files or logging.
Inside cleanup, test the component with the allocated intrinsic before touching it, because the value may arrive empty.
This version prints the buffer size when data exists and stays quiet otherwise.
subroutine cleanup(self)
implicit none
type(buffer), intent(inout) :: self
if (allocated(self%data)) print *, size(self%data)
end subroutine cleanup
Design for cleanup
Keep final routines short, safe, and repeatable: they must handle half built values and never stop the program with an error.
Release exactly the resources the type owns, and leave shared objects alone so other owners can continue to use them.
With this discipline every exit path cleans up the same way, and callers never need manual teardown calls.
program demo
implicit none
use buffers
type(buffer), allocatable :: b
allocate(b)
allocate(b%data(8))
deallocate(b)
print *, "done"
end program demo
Next: Allocatable arrays
Article author: Arthur Isaev