[J3] Finalization Question

Malcolm Cohen malcolm at nag-j.co.jp
Fri May 27 04:52:36 UTC 2022


Hi Brad,

> Is there any possible function that could be used in a specification expression, that would return a type that has a final subroutine?

Yes, yes there is. It can only be used in specification expressions that are not required to be constant expression, so a main program does not cut the mustard. An array bound in a subroutine does though.

A specification function is what you are looking for here. However, such a function must be pure, and so the final subroutine must be pure, and therefore cannot set a global variable or print a message, so it can be hard to tell whether it ran. If your compiler supports memory allocation tracing, you can use pointer components to observe that yes, the final subroutine does get executed (unless the compiler has a bug!). Or if the compiler does not support memory allocation tracing, you could allocate a 500MB array component in the function (and deallocate it in the finaliser!) and run it a million times to check that you don't run out of virtual memory (or you are on a 500TB machine).

Here is an example.

Module fin
  Type t
    Integer,Private,Pointer :: c => Null()
  Contains
    Final :: tfin
  End Type
Contains
  Pure Subroutine tfin(x)
    Type(t),Intent(InOut) :: x
    If (Associated(x%c)) Deallocate(x%c)
  End Subroutine
  Pure Integer Function t_to_int(y)
    Type(t),Intent(In) :: y
    If (.Not.Associated(y%c)) Error Stop 'Not associated'
    t_to_int = y%c
  End Function
  Pure Type(t) Function int_to_t(z)
    Integer,Intent(In) :: z
    Allocate(int_to_t%c)
    int_to_t%c = z
  End Function
End Module
Program test
  Use fin
  Call testit(17)
Contains
  Subroutine testit(n)
    Real tmp(t_to_int(int_to_t(n)))
    Print *,Size(tmp)
  End Subroutine
End Program

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

-----Original Message-----
From: J3 <j3-bounces at mailman.j3-fortran.org> On Behalf Of Brad Richardson via J3
Sent: Friday, May 27, 2022 3:46 AM
To: j3 at mailman.j3-fortran.org
Cc: Brad Richardson <everythingfunctional at protonmail.com>
Subject: [J3] Finalization Question

Hi All,

Recently we were attempting to write a suite of tests to check compilers for conformance to the standard with regards to finalization.
In Section 7.5.6.3, paragraph 6 states:

If a specification expression in a scoping unit references a function, the result is finalized before execution of the executable constructs in the scoping unit.

We attempted to test this doing something like the following:

subroutine finalize_specification_expression
  character(len=size([object_t()])) :: string end subroutine

No compiler we tried executed the final subroutine of object_t (some couldn't even compile that statement). We submitted a bug report to one compiler team, and received a response that:

A structure constructor is not a function reference, so this does not apply.

And

Structure constructors and array constructors are never finalised.
There is no explicit rule stating this, it is a consequence of the standard never saying that they are finalised.

So the question then is:

Is there any possible function that could be used in a specification expression, that would return a type that has a final subroutine?

I'm leaning towards no there isn't. The only place I believe a specification expression appears is in a type-spec (maybe in an attribute of a declaration?), which, as the standard does say, means it is a constant expression. Since only certain intrinsic functions can appear in constant expressions, I'm failing to see how this paragraph could ever apply.

What do you all think?

Regards,
Brad Richardson




More information about the J3 mailing list