CVS difference for ais/ai-00193.txt
--- ais/ai-00193.txt 1998/10/01 03:20:22 1.2
+++ ais/ai-00193.txt 1999/03/22 22:33:25 1.3
@@ -1,4 +1,5 @@
-!standard 07.06.01 (04) 98-04-09 AI95-00193/02
+!standard 07.06.01 (04) 99-03-21 AI95-00193/03
+!standard 07.06.01 (16)
!class binding interpretation 97-08-19
!status work item 98-04-02
!status received 97-08-19
@@ -6,63 +7,88 @@
!subject Classwide Adjust and exceptions
-For an object (including a component) that is initialized by
-assignment (possibly to an enclosing object), if the Adjust
-procedure is invoked then the object is finalized, even if the Adjust
-procedure raises an exception. By contrast, for an object that
-is initialized by default, the object is not finalized unless default
-initialization completes successfully, i.e. without propagating an exception.
+For a controlled object (including a component) that is initialized
+explicitly by assignment (possibly to an enclosing object), if its Adjust
+procedure is invoked but then fails by propagating an exception,
+it is not specified by the language whether the object is finalized.
+If the object is initialized by assignment from an aggregate, its
+Adjust procedure is not invoked (per AI-00083 and AI-00197), but it is
+finalized. If it is initialized by assignment from something other
+than an aggregate, but its Adjust procedure is not invoked at all
+because initialization fails before that point, then the object is
+For an object that is initialized by default, the object is not
+finalized unless default initialization completes successfully, i.e.
+without propagating an exception.
+The definition of "adjustments due to be performed" is relaxed
+for an assignment operation used for initialization, as opposed to one
+used in an assignment statement.
If an object that is initialized by assignment fails during
-an Adjust operation, should the object nevertheless be finalized? (Yes.)
+an Adjust operation, should the object nevertheless be finalized?
+(This AI recommends that this be unspecified.)
Paragraph 7.6.1(4) says:
... each object ... is finalized if the object was successfully
initialized and still exists.
-This is not correct for objects that are initialized by
+This is relaxed for objects that are initialized by
assignment when an Adjust propagates an exception. For such
-objects, the object is finalized so long as the Adjust operation
-is invoked, whether or not it propagates an exception.
-For objects which are initialized by default, this wording is
-correct; such objects are not finalized unless default initialization
-completes without propagating an exception.
+objects, the object may be finalized so long as the Adjust operation
+is invoked, even if it propagates an exception. It must be finalized
+if the Adjust operation completes successfully.
+For objects which are initialized by default, no change in the
+wording is proposed; such objects are finalized if and only if
+default initialization completes without propagating an exception.
+The definition of "adjustments due to be performed" should be
+relaxed for an assignment operation that is part of initialization,
+thereby allowing initialization to be abandoned as soon as any
+Adjust fails. For an assignment statement, it is important
+that all adjustments be performed, even if one fails, because
+all controlled subcomponents are going to be finalized.
-When an object (including a component) is initialized by an assignment,
-the Adjust operation is invoked. If this operation propagates
-an exception, then other Adjust operations that are already due
-to be performed are performed, and then Program_Error is raised.
-What this means is that if you have a composite object with multiple
-controlled parts, if one of the Adjust operations fails, the others
-are still invoked. Clearly those parts for which Adjust succeeds
-should be finalized per 7.6.1(4). However, 7.6.1(4) implies that
-the ones for which Adjust fails should not be finalized. However,
-for implementations that "bundle" all of the Adjust operations for
-all controlled parts of a composite type into a single
+When an object (including a component) is initialized by an assignment
+other than from an aggregate, the Adjust operation is invoked.
+If this operation propagates an exception, then other Adjust operations
+that are already due to be performed are performed, and then Program_Error
+What this means is that if you have a composite object which is
+initialized by an assignment from something other than an aggregate,
+and it has multiple controlled parts, then if one of the Adjust
+operations fails, the others are still invoked. Clearly those parts for
+which Adjust succeeds should be finalized per 7.6.1(4). However,
+7.6.1(4) implies that the ones for which Adjust fails should not be
+finalized. However, for implementations that "bundle" all of the Adjust
+operations for all controlled parts of a composite type into a single
"adjust-whole-object" procedure, it is burdensome to keep track
of which parts failed and which succeeded, and only finalize those
-whose Adjust succeeded. Furthermore, if some of the Adjust operations
+whose Adjust succeeded. Note that if some of the Adjust operations
had failed in an assignment statement, all parts would ultimately
-still be finalized when the scope is existed.
+still be finalized when the scope is existed.
One of the important goals of the finalization model with respect to
-exceptions (paragraphs 7.6.1(14-18)) is that if one controlled
+exceptions (paragraphs 7.6.1(14-18)) is that if one controlled
abstraction fails by raising an exception in Adjust or
-Finalize, this failure should not spread to other unrelated controlled
-abstractions. Even if a single composite object happens to have
+Finalize, this failure should not spread to other unrelated controlled
+abstractions. Even when one composite object happens to have
two controlled parts, one from the "failed" abstraction and one
from the "still-good" abstraction, the "still-good" abstraction should
still have Adjust and Finalize called the appropriate number of times
@@ -70,40 +96,22 @@
Given this goal, the "bundling" of Adjust operations, and the
correspondence with assignment statements, it seems best to
-require that so long as Adjust is invoked on an object being
-initialized via assignment, Finalize will be invoked on the object.
+allow that, so long as the Adjust routine has been invoked on an
+object being initialized, Finalize may be invoked on the object.
-As a point of clarification, adjustments "due to be performed"
-are all those associated with a single assignment operation.
-If a composite object is default initialized, and it has
-two controlled components each of which has its own
-explicit initialization expression, the adjustment of the
-second controlled component is not "due to be performed" just because
-the first controlled component's adjust operation has been
-invoked. By contrast, if such a composite object is initialized
-as a whole by assignment, then the adjust operations of all of its
-controlled parts are "due to be performed" as soon as the bytes
-representing the source (right-hand-side) of the assignment operation
-are copied on to the composite object being initialized.
-Hence, in the default initialization case, if the Adjust operation of
-the first controlled component fails, the initialization of the second
-controlled component can be skipped completely, and only the
-Finalize operation of the first component will be called as part
-of propagating the Program_Error due to the adjustment failure.
-In the case where the composite object is initialized as a whole by
-assignment, the Adjust operation of both components will be invoked,
-even if the first one fails, and both Finalize operations will be
-Note that since order is not generally specified for
-initialization of components as part of default initialization,
-it is possible for the "second" component to be initialized first,
-and presuming that succeeds, both components would end up being
-adjusted and so both would be finalized. Note that if both Adjust
-routines are going to fail, in the default initialization case, only
-one of them would be invoked. In the case of initialization by assignment
-to the composite object, both would be invoked.
+On a somewhat separate issue, the notion of adjustments
+"due to be performed" (7.6.1(16)) need not apply to initialization
+by assignment. So long as a subcomponent is not going to be
+finalized, it need not be adjusted, even if it is initialized
+as part of an enclosing composite assignment operation for
+which some adjustments are performed. On the other hand,
+for an assignment that is part of an assignment statement,
+it is important that all adjustments be attempted, even if some
+of them fail, since all subcomponents are going to be finalized.
+This relaxation for adjustments that occur during initialization
+means that an initialization may be abandoned as soon as any
+Adjust fails, so long as those components which have never been
+adjusted are not finalized.
@@ -117,8 +125,8 @@
To support (explicit) initialization and assignment of classwide
objects, our compiler generates an "Adjust_Whole_Object" routine for every
non-limited tagged type. We dispatch to the appropriate one based
-on the tag of the classwide value being adjusted. It now appears we
-need to create two "Adjust_Whole_Object" routines, one for use in
+on the tag of the classwide value being adjusted. It now appears we
+need to create two "Adjust_Whole_Object" routines, one for use in
initialization, and one for use in assignment. Before we launch off on that
additional work, I wanted to confirm my RM interpretation with others.
@@ -131,19 +139,19 @@
is set, raises Program_Error. The Adjust_Whole_Object routine
is called with aborts deferred, either as part of initializing
a classwide object by copy, or as part of a classwide assignment statement.
-In the case of initialization, we "register" the whole object for
+In the case of initialization, we "register" the whole object for
finalization (we have a Finalize_Whole_Object routine which will
-clean it up) only if the Adjust_Whole_Object succeeds.
+clean it up) only if the Adjust_Whole_Object succeeds.
-The problem is, if the Adjust_Whole_Object propagates Program_Error,
+The problem is, if the Adjust_Whole_Object propagates Program_Error,
then we don't register the whole object for finalization. We also
don't register any part of the object for finalization, even
those parts that were successfully adjusted, since we don't have
-any record of which parts succeeded versus which parts failed.
-This seems to violate the requirement of 7.6.1(4) which says
-that any object that is successfully initialized must be finalized.
+any record of which parts succeeded versus which parts failed.
+This seems to violate the requirement of 7.6.1(4) which says
+that any object that is successfully initialized must be finalized.
There seems to be no problem with Adjust_Whole_Object for the
purposes of an assignment statement, because there is no need
@@ -153,7 +161,7 @@
The straightforward solution to this problem is to have a separate
Adjust_Whole_Object_For_Initialization routine for each tagged
type, which rather than just raising Program_Error when one or more
-parts fail to adjust, will also finalize any parts that were successfully
+parts fail to adjust, will also finalize any parts that were successfully
adjusted before raising Program_Error.
@@ -164,9 +172,9 @@
and then live with the fact that we are going to finalize parts
whose Adjust failed. That could happen as a result of an assignment
statement anyway, and the only thing being corrupted is a part
-that was already "hosed" to begin with.
+that was already "hosed" to begin with.
-Another possibility is to leave things as we have them now, which
+Another possibility is to leave things as we have them now, which
means no part is finalized if any parts fail. The problem with that
is that one messed up controlled abstraction can have the effect
of progressively messing up any other controlled abstraction, just
Questions? Ask the ACAA Technical Agent