[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