[J3] [EXTERNAL] [BULK] Clarification needed on finalization

Malcolm Cohen malcolm at nag-j.co.jp
Thu Jan 18 23:49:14 UTC 2024


I agree with Tom.

 

Allocatable thingos are finalised on deallocation. This is explicitly stated in the standard: “When an allocatable entity is deallocated, it is finalized

unless it is the variable in an intrinsic assignment statement”.

 

A value created by a structure constructor or array constructor is itself not finalised. This is explicitly omitted from the standard – there was an interp about this.

 

Compiler-generated temporaries are never finalised. This is explicitly omitted from the standard. A compiler can *and does* generate temporary copies of things all the time, moving them between registers and memory, making extra copies for alignment or parallel update purposes, in fact any time it feels like it. It would be a disaster if the standard allowed compilers to randomly insert procedure calls all over the place!

 

I see no actual ambiguity here.

 

I do agree that finalisation is not easy to understand. Doubtless the wording could be improved, but I am leery of “wording improvements” that accidentally make technical changes – we have shot ourselves in the feet many times by doing exactly that, and have had to undo the wording “improvement” via interp.

 

Splitting p1 of 7.5.6.3 to separate the allocatable and non-allocatable cases completely might be a good idea. But that would not, I think, affect this question, which is answered by p2 already anyway.

 

Cheers,

-- 

..............Malcolm Cohen, NAG Oxford/Tokyo.

 

From: J3 <j3-bounces at mailman.j3-fortran.org> On Behalf Of Clune, Thomas L. (GSFC-6101) via J3
Sent: Friday, January 19, 2024 3:31 AM
To: General J3 interest list <j3 at mailman.j3-fortran.org>
Cc: Clune, Thomas L. (GSFC-6101) <thomas.l.clune at nasa.gov>
Subject: Re: [J3] [EXTERNAL] [BULK] Clarification needed on finalization

 

I‘ll defer to others for references in the standard, but …

 

NAG calls the finalizer twice, which is what I would expect as a user.

 

*	0 times is a memory leak
*	4 times means that a resource got freed twice which will generally be an error in real code
*	2 objects created.  2 object destroyed.

 

Copy-in should never call the finalizer.   This would render the object in an inconsistent state if say the finalizer was closing a netcdf file handle.

 

I think the same is true for copy-out, but I’m less clear and in a rush …

 

*	Tom

 

From: J3 < <mailto:j3-bounces at mailman.j3-fortran.org> j3-bounces at mailman.j3-fortran.org> on behalf of j3 < <mailto:j3 at mailman.j3-fortran.org> j3 at mailman.j3-fortran.org>
Reply-To: j3 < <mailto:j3 at mailman.j3-fortran.org> j3 at mailman.j3-fortran.org>
Date: Thursday, January 18, 2024 at 11:46 AM
To: j3 < <mailto:j3 at mailman.j3-fortran.org> j3 at mailman.j3-fortran.org>
Cc: Mark LeAir < <mailto:mleair at nvidia.com> mleair at nvidia.com>
Subject: [EXTERNAL] [BULK] [J3] Clarification needed on finalization

 


CAUTION: This email originated from outside of NASA.  Please take care when clicking links or opening attachments.  Use the "Report Message" button to report suspicious messages to the NASA SOC. 

 

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:

```

module repro

  type finalizable

   integer :: i

  contains

    final :: print_finalized

  end type

  type t

    type(finalizable), allocatable :: x

  end type

contains

  subroutine sub(x)

    type(t), intent(in) :: x(2)

    print *, "in sub"

  end subroutine

  subroutine print_finalized(x)

    type(finalizable), intent(inout) :: x

    print *, "finalizing t(finalizable)", x%i

  end subroutine

end module

 

  use repro

  call sub([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.

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.j3-fortran.org/pipermail/j3/attachments/20240119/6b2d235e/attachment-0001.htm>


More information about the J3 mailing list