(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