(j3.2006) finalizer issues

Malcolm Cohen malcolm
Mon Jun 17 03:43:18 EDT 2013


>(1)  The second sentence of paragraph 2 of Clause 4.5.6.2 [76:6-7] states
>
>      A final subroutine shall not reference or
>      define an object that has already been
>      finalized.

This is following the first sentence, which is

  "If several entities are to be finalized as a consequence of an event 
specified in 4.5.6.3, the order in which they are finalized is processor 
dependent."

The second sentence is continuing to talk about the same situation the first 
sentence just set up.
...
> It is not obvious what the restriction should be.

It was to me... I won't claim that the wording is clear, but this style 
(subsequent sentences of a paragraph further discussing what earlier sentences 
set up) is widespread throughout the standard, not just here.

I have made a note of the potential for misunderstanding for my upcoming 
editorial paper, perhaps changing the problematic sentence to something like
  "During this process, execution of a final subroutine for one of these 
entities shall not reference or define any of the other entities that have 
already been finalized."
???  Seems a bit messy, but maybe it will do.

Basically, IIRC the intent here was to permit the processor to recover the 
actual storage for an object once it has been finalised, but without forbidding 
the final subroutines from changing things that might be finalised later in the 
process.  I am thinking here of schemes where one ends up with a tree or forest 
of expressions with pointers to variables, getting "unwound" (and partly 
evaluated) on procedure exist ... in such a case it is certainly desirable to be 
able to reference other variables that are about to become undefined, and it 
would be up to the final subroutine to ensure the data structures being modified 
removed references to the object being finalised.

>(2)  The fifth paragraph (formerly the fourth paragraph) of Clause 4.5.6.3
>[[76:15-16] states
>
>      If an executable construct references a
>      function, the result is finalized after
>      execution of the innermost executable
>      construct containing the reference.
...
>I recall the question whether the results of function references in
>array and structure constructors that are constant expressions are finalized
>being considered during discussion of interpretation F08/0011.  I thought we
>decided that the results are not finalized,

Obviously not... executable statements never contain a <constant-expr> that is 
finalisable anyway.

> but I cannot find language to that effect.

Indeed, you found the language that contradicts that idea.

>  I am uncertain if execution of
>
>       WRITE (10) [ ((MERGE(T1), T(1), .TRUE.), I = 1, 1000000) ]
>
>causes any finalization.

Well, the text you quoted says it does.

>(3)  Paragraph 3 of Clause 4.5.6.2 [76:8] states
>
>      If an object is not finalized, it retains
>      its definition status and does not become
>      undefined.
>
>That statement seems mostly harmless and, perhaps, pointless.  It might be
>taken, however, to imply that if an object is finalized, it becomes undefined.
>I found no evidence for that in the standard, but I might have missed 
>something.

In most cases it does become undefined.  Even in assignment, one might think 
that the variable becomes transiently undefined while the value is being copied 
in...

I agree that the sentence does not add much to the description.  I think this 
originally (00-277r2) comes from the paragraph
  "A nonpointer nonallocatable object that is not a dummy argument or function 
result is finalized immediately before it would become undefined due to 
execution of a RETURN or END statement (14.7.6, item (3)).  If the object is 
defined in a module and there are no longer any active procedures referencing 
the module, it is processor-dependent whether it is finalized.  If the object is 
not finalized, it retains its definition status and does not become undefined."

I think this sentence is just the generalisation of that... certainly it is only 
talking about finalisable objects, otherwise it doesn't make sense!  Perhaps it 
has outlived its usefulness?  (It got changed sometime in the transition from 
06-007 to 07-007r1, but my search didn't turn up the paper that did it.)

>(4)  Suppose X and Y are nonpointer, nonallocatable variables of the same
>finalizable type.  Suppose the final subroutine for X might reference X and
>might change the value of Y.  Then execution of the intrinsic assignment X = Y
>is equivalent to saving a copy of the value of Y, finalizing X, and then 
>copying
>the saved value to X.

An interesting supposition.  That depends on whether you think "evaluating" Y 
means taking a copy of its value... (I would tend to agree that it does).

>Suppose the function F returns a value of the same type as X and Y.  Then
>execution of the intrinsic assignment X = F(Y) is equivalent to saving a copy 
>of
>the value of F(Y), finalizing X, copying the saved value to X, and then
>finalizing the saved value.

This seems perfectly normal and straightforward.  After all, F(Y) is permitted 
to reference X (supposing it has some path to it) and X=F(X) is also valid.  I 
don't see anything particularly surprising here, in fact evaluating F(...) is 
precisely what we want done before dropping the bits into X.

>I read a Fortran textbook that advises users to provide a final subroutine for
>all derived types that include pointer components that deallocate those
>components.

Politeness forbids me from commenting on incomplete, misleading or otherwise 
wrong-headed advice.

>  Users who take that advice are likely to be surprised when after an
>intrinsic assignment

defined assignment is essential in cases like this, and I have only ever seen it 
(auto deallocation of pointer components via finalisers) advocated in 
conjunction with defined assignment.

Cheers,
-- 
................................Malcolm Cohen, Nihon NAG, Tokyo. 




More information about the J3 mailing list