[Fortran] PR37336 - FIINAL patch [1/n]: Implement the finalization wrapper subroutine
Tobias Burnus
burnus@net-b.de
Sat Aug 25 20:07:00 GMT 2012
Mikael Morin wrote:
>>> What if only comp's subcomponents are finalizable, the finalization
>>> wrapper should still be called, shouldn't it?
>> Well, that's handled in the "else" branch. There, I walk all
>> subcomponents. I do not need to walk them in case there is a finalizer
>> as the called finalization wrapper will handle them.
> Actually, I don't understand why you walk twice over the subcomponents:
> in the else branch here and in the finalizer.
Well, I only walk once per component. However, I could unconditionally
call this function â and move some of the checks from the main program here.
>>> If comp has finalizable subcomponents, it has a finalization wrapper,
>>> which is (or should be) caught above, so this branch is (or should be)
>>> unreachable.
>> I probably miss something, but I don't see why this branch should be
>> unreachable. One has:
>>
>> if (component is allocatable)
>> call DEALLOCATE(comp) ! which might invoke finalizers
>> else if (component itself has a finalizer)
>> call FINAL_WRAPPER
>> else
>> for all nonpointer subcomponents which are allocatables, have
>> finalizers or have allocatable/finalizable components, call
>> finalize_component.
>> end if
> I expected something like:
> if (allocatable)
> call deallocate (comp)
> else if (finalizer or subcomponents have a finalizer)
> call FINAL_WRAPPER
Well, the question is whether one wants to call a finalize wrapper for a
simple "comp%alloctable_int(10)" or not. In the current scheme, I tried
to avoid calling a finalizer wrapper for simple allocatable components.
Thus, one has the choice:
a) Directly call DEALLOCATE for alloctable components of subcomponents
b) Always call the finalizer wrapper â also for nonalloctable TYPEs
(with finalizable/allocatable components)
(a) is more direct and possibly a bit faster while (b) makes the wrapper
function a tad smaller.
> As said above, I don't understand why you would walk over the components
> twice
I don't. I touch every ((sub)sub)component only once; I only do a deep
walk until there is either no component or a pointer or an allocatable
or a finalizable component. I do acknowledge that I repeat some of the
logic by handling the outer component in the wrapper and the inner
(sub)subcomponents in the final_components.
>>>>> + else if (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
>>>>> + && CLASS_DATA (comp)->attr.allocatable)
>>>>> + alloc_comp = true;
>>> Shouldn't one assume without condition that there are allocatable or
>>> finalizable subcomponents when there is a polymorphic component?
>> Well, we do not deallocate/finalize polymorphic POINTER components.
> Indeed, then I prefer having !CLASS_DATA(comp)->attr.pointer.
Okay, that's equivalent; though, I have to admit that I prefer the
current version, which I regard as cleaner.
* * *
Regarding the flag or nonflag final_comp, I have to admit that I still
do not completely understand how you would implement it.
One option would be something like the following
bool has_final_comp(derived) {
for (comp = derived->components; comp; comp = comp->next)
{
if (comp->attr.pointer)
continue;
if (comp->f2k_derived->finalizers || comp->ts.type == BT_CLASS)
return true;
if (comp->ts.type == BT_DERIVED
&& has_final_comp(comp->ts.u.derived))
return true;
}
return false
}
in class.c
Another is the version which gets set in parse.c.
However, I do not understand what you mean by:
> If performance is a problem, the function could use the flag as a
> backend. As long as the field is used and set in a single place, I
> don't mind. I don't have a strong opinion either, there is already a
> full bag of flags; one more wouldn't make things dramatically worse.
Tobias
More information about the Fortran
mailing list