[J3] Clarification needed on finalization

Toon Moene toon at moene.org
Thu Jan 18 18:44:52 UTC 2024


Results on gfortran-13:

toon at yoga:~/src$ gfortran mark.f90
toon at yoga:~/src$ ./a.out
  in sub
  finalizing t(finalizable)           1
  finalizing t(finalizable)           2

Lets make it a competition :-)

Kind regards,
Toon Moene.

On 1/18/24 17:46, Mark LeAir via J3 wrote:

> Hi Everyone,
> 
> One of the Flang developers forwarded me the following question below. 
> Can anyone clarify this with the current Standard?  Or do I need to 
> submit an Interp for the next meeting?
> 
> Thanks,
> 
> Mark
> 
> 
> I was looking at a test failure with flang and the expected behavior is 
> not clear to me.
> 
> With structure constructors and array constructors, it is possible to 
> create values of a derived type with allocatable components. These 
> values are neither named, nor function results.
> 
> Fortran 2023 does not really say when and if such components are 
> automatically deallocated in section 9.7.3.2 Deallocation of allocatable 
> variables.
> 
> So, it is not clear how to exactly apply the sentence related to 
> finalization in the same section: “/If an allocatable component is a 
> subobject of a finalizable object, any final subroutine for that object 
> is executed before the component is automatically deallocated.”/
> 
> //
> 
> Obviously, the compiler should deallocate the memory of such temporary 
> to avoid leaks after use, but it is not clear to me if this qualifies as 
> Fortran “automatic deallocation”. Otherwise, why shouldn’t we also 
> finalize it when making a temporary in a copy-in/copy-out situation.
> 
> So,*my question is, given a type `with_finalizable_alloc_comp`, that has 
> some allocatable component `alloc_comp` with a final routine 
> `finalizer`, how many times should `finalizer` be called in something 
> like `print *, [with_finalizable_alloc_comp(alloc_comp=1), 
> with_finalizable_alloc_comp(alloc_comp=2)]`?*
> 
> Depending on how you implement and read things, I think this could 
> currently be anything in 0 times, 2 times or 4 times.
> 
> Rational:
> 
> - 0 time: this is neither a function result/named variable and no 
> paragraph in 9.7.3.2 apply.
> 
> - 2 times: finalize the “whole expression” (that is, and expression that 
> is an actual argument or does not appear in a parent expression). 
> Tempting but badly defined in my opinion.
> 
> - 4 times: regard a structure constructor and an array constructor as 
> functions returning values and apply 9.7.3.2 for 
> `array_ctor(struct_ctor(1), struct_ctor(2))`. Well defined, but probably 
> not optimal.
> 
> I would advocate for 0 time.
> 
> Here is a reproducer:
> 
> ```
> 
> modulerepro
> 
> typefinalizable
> 
> integer:: i
> 
> contains
> 
> final:: print_finalized
> 
> endtype
> 
> typet
> 
> type(finalizable), allocatable:: x
> 
> endtype
> 
> contains
> 
> subroutinesub(x)
> 
> type(t), intent(in) :: x(2)
> 
> print*, "in sub"
> 
> endsubroutine
> 
> subroutineprint_finalized(x)
> 
> type(finalizable), intent(inout) :: x
> 
> print*, "finalizing t(finalizable)", x%i
> 
> endsubroutine
> 
> endmodule
> 
> userepro
> 
> callsub([t:: t(x=finalizable(1)), t(x=finalizable(2))])
> 
> end
> 
> ```
> 
> - ifx (and flang currently): call finalizer 0 times.
> 
> - gfortran and nagfor: call finalizer 2 times.
> 
> - xlf: call finalizer 4 times.
> 
> So… some clarification is needed here I think.
> 

-- 
Toon Moene - e-mail: toon at moene.org - phone: +31 346 214290
Saturnushof 14, 3738 XG  Maartensdijk, The Netherlands



More information about the J3 mailing list