[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