[J3] Finalization Question

Brad Richardson everythingfunctional at protonmail.com
Fri May 27 15:59:47 UTC 2022


Hi Malcolm,

This was the explanation I needed. It clarifies the two points I was
missing.

1. A specification expression need not be a constant expression in some
places (namely in procedures).
2. The final subroutine must be pure in order for the type to be used
in a specification expression.

I think I can find a way to cheat in order to observe the execution of
the final subroutine without resorting to an external tool.
Specifically, lie about the purity of a procedure via an interface
block within the final subroutine.

Thanks for the help.

Regards,
Brad

On Fri, 2022-05-27 at 13:52 +0900, Malcolm Cohen via J3 wrote:
> 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