Generalized Finalization (GNAT Reference Manual) (original) (raw)
17.3.7 Generalized Finalization ¶
The Finalizable
aspect can be applied to any record type, tagged or not, to specify that it provides the same level of control on the operations of initialization, finalization, and assignment of objects as the controlled types (see RM 7.6(2) for a high-level overview). The only restriction is that the record type must be a root type, in other words not a derived type.
The aspect additionally makes it possible to specify relaxed semantics for the finalization operations by means of the Relaxed_Finalization
setting.
Example:
type Ctrl is record Id : Natural := 0; end record with Finalizable => (Initialize => Initialize, Adjust => Adjust, Finalize => Finalize, Relaxed_Finalization => True);
procedure Adjust (Obj : in out Ctrl); procedure Finalize (Obj : in out Ctrl); procedure Initialize (Obj : in out Ctrl);
The three procedures have the same profile, taking a single in out T
parameter.
We follow the same dynamic semantics as controlled objects:
Initialize
is called when an object of typeT
is declared without default expression.Adjust
is called after an object of typeT
is assigned a new value.Finalize
is called when an object of typeT
goes out of scope (for stack-allocated objects) or is explicitly deallocated (for heap-allocated objects). It is also called when on the value being replaced in an assignment.
However the following differences are enforced by default when compared to the current Ada controlled-objects finalization model:
- No automatic finalization of heap allocated objects:
Finalize
is only called when an object is implicitly deallocated. As a consequence, no-runtime support is needed for the implicit case, and no header will be maintained for this in heap-allocated controlled objects.
Heap-allocated objects allocated through a nested access type definition will hence ‘not’ be deallocated either. The result is simply that memory will be leaked in those cases. - The
Finalize
procedure should have have the No_Raise aspect specified. If that’s not the case, a compilation error will be raised.
Additionally, two other configuration aspects are added,Legacy_Heap_Finalization
and Exceptions_In_Finalize
:
Legacy_Heap_Finalization
: Uses the legacy automatic finalization of heap-allocated objectsExceptions_In_Finalize
: Allow users to have a finalizer that raises exceptions ‘NB!’ note that using this aspect introduces execution time penalities.