Finalization ifort vs gfortran

I’ve encountered this problem before, where the finalizer works “earlier” than you expect it too.

type :: holds_pointer
   type(c_ptr) :: handle = c_null_ptr   ! points to heap memory
contains
   final :: shutdown       ! releases the handle
   procedure :: use_handle
end type

type(holds_pointer) :: instance

instance = create_instance()
call instance%use_handle()  ! KA-BOOM! (Invalid handle)

The problem is really not the finalizer, but the fact that object creation, destruction, and copying are tightly linked operations. In C++ they call this the rule of three or “the big three”. Quoting Wikipedia, the rule claims that if a class defines any of the following then it should probably explicitly define all three:

  • destructor
  • copy constructor
  • copy assignment operator

Fortran doesn’t have such a thing as a copy constructor. You could fix the problem by overloading the assignment operator, but this has it’s own subtle problems (i.e. does the assignment perform a deep copy or a shallow copy of the pointer?).

There are (at least) two ways to fix this: