On 25/08/2012 22:06, Tobias Burnus wrote: >>>> 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. OK, this is a deliberate choice of implementation to avoid call overhead. I slightly prefer (b), but we can keep (a). I'm fine with (a) if the code walking the components is shared - which avoids c vs. comp issues by the way ;-) .
> * * * > > 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 } This was my initial proposition. The benefit is it is very clear how it works compared to manual setting the flag here and there. As you raised a performance issue, I proposed something like this: bool has_final_comp(derived) { bool retval = false; if (derived->cache.final_comp_set) return derived->cache.final_comp; for (comp = derived->components; comp; comp = comp->next) { if (comp->attr.pointer) continue; if (comp->f2k_derived->finalizers || comp->ts.type == BT_CLASS) { retval = true; break; } if (comp->ts.type == BT_DERIVED && has_final_comp(comp->ts.u.derived)) { retval = true; break; } } derived->cache.final_comp_set = 1; derived->cache.final_comp = retval; return retval; } It's no big deal anyway. I dream of a compiler where all the non-standard symbol attribute flags, expression rank and typespec, etc, would be implemented like this... No need for resolution, etc; it would just work everywhere. I know the story, patches welcome; they may come, one day... Mikael