1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<TITLE>Ada95 - User-Defined Assignment and Finalization</TITLE>
<META NAME="Author" CONTENT="JTC1/SC22/WG9/ARG, by Randall Brukardt, ARG Editor">
<META NAME="GENERATOR" CONTENT="Arm_Form.Exe, Ada Reference Manual generator">
<STYLE type="text/css">
DIV.paranum {position: absolute; font-family: Arial, Helvetica, sans-serif; left: 0.5 em; top: auto}
TT {font-family: "Courier New", monospace}
DT {display: compact}
DIV.Normal {font-family: "Times New Roman", Times, serif; margin-bottom: 0.6em}
DIV.Wide {font-family: "Times New Roman", Times, serif; margin-top: 0.6em; margin-bottom: 0.6em}
DIV.Annotations {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-bottom: 0.6em}
DIV.WideAnnotations {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0.6em; margin-bottom: 0.6em}
DIV.Index {font-family: "Times New Roman", Times, serif}
DIV.SyntaxSummary {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.4em}
DIV.Notes {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.6em}
DIV.NotesHeader {font-family: "Times New Roman", Times, serif; margin-left: 2.0em}
DIV.SyntaxIndented {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-bottom: 0.4em}
DIV.Indented {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-bottom: 0.6em}
DIV.CodeIndented {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-bottom: 0.6em}
DIV.SmallIndented {font-family: "Times New Roman", Times, serif; margin-left: 10.0em; margin-bottom: 0.6em}
DIV.SmallCodeIndented {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-bottom: 0.6em}
DIV.Examples {font-family: "Courier New", monospace; margin-left: 2.0em; margin-bottom: 0.6em}
DIV.SmallExamples {font-family: "Courier New", monospace; font-size: 80%; margin-left: 7.5em; margin-bottom: 0.6em}
DIV.IndentedExamples {font-family: "Courier New", monospace; margin-left: 8.0em; margin-bottom: 0.6em}
DIV.SmallIndentedExamples {font-family: "Courier New", monospace; font-size: 80%; margin-left: 15.0em; margin-bottom: 0.6em}
UL.Bulleted {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.SmallBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.NestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.SmallNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.IndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.CodeIndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.CodeIndentedNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-right: 8.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.SyntaxIndentedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.NotesBulleted {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
UL.NotesNestedBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
DL.Hanging {font-family: "Times New Roman", Times, serif; margin-top: 0em; margin-bottom: 0.6em}
DD.Hanging {margin-left: 6.0em}
DL.IndentedHanging {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0em; margin-bottom: 0.6em}
DD.IndentedHanging {margin-left: 2.0em}
DL.HangingInBulleted {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.HangingInBulleted {margin-left: 4.0em}
DL.SmallHanging {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-top: 0em; margin-bottom: 0.6em}
DD.SmallHanging {margin-left: 7.5em}
DL.SmallIndentedHanging {font-family: "Times New Roman", Times, serif; margin-left: 8.0em; margin-top: 0em; margin-bottom: 0.6em}
DD.SmallIndentedHanging {margin-left: 2.0em}
DL.SmallHangingInBulleted {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.SmallHangingInBulleted {margin-left: 5.0em}
DL.Enumerated {font-family: "Times New Roman", Times, serif; margin-right: 0.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.Enumerated {margin-left: 2.0em}
DL.SmallEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 4.0em; margin-right: 4.0em; margin-top: 0em; margin-bottom: 0.5em}
DD.SmallEnumerated {margin-left: 2.5em}
DL.NestedEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 2.0em; margin-right: 2.0em; margin-top: 0em; margin-bottom: 0.5em}
DL.SmallNestedEnumerated {font-family: "Times New Roman", Times, serif; margin-left: 6.0em; margin-right: 6.0em; margin-top: 0em; margin-bottom: 0.5em}
</STYLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFF0" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
<P><A HREF="RM-TOC.html">Contents</A> <A HREF="RM-0-29.html">Index</A> <A HREF="RM-7-5.html">Previous</A> <A HREF="RM-7-6-1.html">Next</A></P>
<HR>
<H1> 7.6 User-Defined Assignment and Finalization</H1>
<DIV Class="Paranum"><FONT SIZE=-2>1</FONT></DIV>
<DIV Class="Normal"> <A NAME="I3114"></A><A NAME="I3115"></A>Three
kinds of actions are fundamental to the manipulation of objects: initialization,
finalization, and assignment. Every object is initialized, either explicitly
or by default, after being created (for example, by an <FONT FACE="Arial, Helvetica">object_declaration</FONT>
or <FONT FACE="Arial, Helvetica">allocator</FONT>). Every object is finalized
before being destroyed (for example, by leaving a <FONT FACE="Arial, Helvetica">subprogram_body</FONT>
containing an <FONT FACE="Arial, Helvetica">object_declaration</FONT>,
or by a call to an instance of Unchecked_Deallocation). An assignment
operation is used as part of <FONT FACE="Arial, Helvetica">assignment_statement</FONT>s,
explicit initialization, parameter passing, and other operations. <A NAME="I3116"></A><A NAME="I3117"></A><A NAME="I3118"></A></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>2</FONT></DIV>
<DIV Class="Normal"> Default definitions for these three fundamental
operations are provided by the language, but <A NAME="I3119"></A>a <I>controlled</I>
type gives the user additional control over parts of these operations.
<A NAME="I3120"></A><A NAME="I3121"></A><A NAME="I3122"></A>In particular,
the user can define, for a controlled type, an Initialize procedure which
is invoked immediately after the normal default initialization of a controlled
object, a Finalize procedure which is invoked immediately before finalization
of any of the components of a controlled object, and an Adjust procedure
which is invoked as the last step of an assignment to a (nonlimited)
controlled object. </DIV>
<H4 ALIGN=CENTER>Static Semantics</H4>
<DIV Class="Paranum"><FONT SIZE=-2>3</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> The following language-defined
library package exists: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>4/1</FONT></DIV>
<DIV Class="Examples"><TT><B>package</B> Ada.Finalization <B>is</B><A NAME="I3123"></A><A NAME="I3124"></A><A NAME="I3125"></A><BR>
<B>pragma</B> Preelaborate(Finalization);<BR>
<B>pragma</B> Remote_Types(Finalization);</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>5</FONT></DIV>
<DIV Class="Examples"><TT> <B>type</B> <A NAME="I3126"></A><A NAME="I3127"></A>Controlled <B>is abstract tagged private</B>;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>6</FONT></DIV>
<DIV Class="Examples"><TT> <B>procedure</B> <A NAME="I3128"></A><A NAME="I3129"></A>Initialize (Object : <B>in out</B> Controlled);<BR>
<B>procedure</B> <A NAME="I3130"></A><A NAME="I3131"></A>Adjust (Object : <B>in out</B> Controlled);<BR>
<B>procedure</B> <A NAME="I3132"></A><A NAME="I3133"></A>Finalize (Object : <B>in out</B> Controlled);</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>7</FONT></DIV>
<DIV Class="Examples"><TT> <B>type</B> <A NAME="I3134"></A><A NAME="I3135"></A>Limited_Controlled <B>is abstract tagged limited private</B>;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>8</FONT></DIV>
<DIV Class="Examples"><TT> <B>procedure</B> <A NAME="I3136"></A><A NAME="I3137"></A>Initialize (Object : <B>in out</B> Limited_Controlled);<BR>
<B>procedure</B> <A NAME="I3138"></A><A NAME="I3139"></A>Finalize (Object : <B>in out</B> Limited_Controlled);<BR>
<B>private</B><BR>
... -- <I>not specified by the language</I><BR>
<B>end</B> Ada.Finalization;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>9</FONT></DIV>
<DIV Class="Normal"> <A NAME="I3140"></A>A controlled type is a descendant
of Controlled or Limited_Controlled. The (default) implementations of
Initialize, Adjust, and Finalize have no effect. The predefined "="
operator of type Controlled always returns True, since this operator
is incorporated into the implementation of the predefined equality operator
of types derived from Controlled, as explained in <A HREF="RM-4-5-2.html">4.5.2</A>.
The type Limited_Controlled is like Controlled, except that it is limited
and it lacks the primitive subprogram Adjust. </DIV>
<H4 ALIGN=CENTER>Dynamic Semantics</H4>
<DIV Class="Paranum"><FONT SIZE=-2>10</FONT></DIV>
<DIV Class="Normal"> <A NAME="I3141"></A>During the elaboration of
an <FONT FACE="Arial, Helvetica">object_declaration</FONT>, for every
controlled subcomponent of the object that is not assigned an initial
value (as defined in <A HREF="RM-3-3-1.html">3.3.1</A>), Initialize is
called on that subcomponent. Similarly, if the object as a whole is controlled
and is not assigned an initial value, Initialize is called on the object.
The same applies to the evaluation of an <FONT FACE="Arial, Helvetica">allocator</FONT>,
as explained in <A HREF="RM-4-8.html">4.8</A>.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>11/1</FONT></DIV>
<DIV Class="Normal"> For an <FONT FACE="Arial, Helvetica">extension_aggregate</FONT>
whose <FONT FACE="Arial, Helvetica">ancestor_part</FONT> is a <FONT FACE="Arial, Helvetica">subtype_mark</FONT>,
for each controlled subcomponent of the ancestor part, either Initialize
is called, or its initial value is assigned, as appropriate; if the type
of the ancestor part is itself controlled, the Initialize procedure of
the ancestor type is called, unless that Initialize procedure is abstract.
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>12</FONT></DIV>
<DIV Class="Normal"> Initialize and other initialization operations
are done in an arbitrary order, except as follows. Initialize is applied
to an object after initialization of its subcomponents, if any (including
both implicit initialization and Initialize calls). If an object has
a component with an access discriminant constrained by a per-object expression,
Initialize is applied to this component after any components that do
not have such discriminants. For an object with several components with
such a discriminant, Initialize is applied to them in order of their
<FONT FACE="Arial, Helvetica">component_declaration</FONT>s. For an <FONT FACE="Arial, Helvetica">allocator</FONT>,
any task activations follow all calls on Initialize. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>13</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> <A NAME="I3142"></A>When
a target object with any controlled parts is assigned a value, either
when created or in a subsequent <FONT FACE="Arial, Helvetica">assignment_statement</FONT>,
the <I>assignment operation</I> proceeds as follows: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>14</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>The value of the target becomes the assigned value.</LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>15</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC><A NAME="I3143"></A><A NAME="I3144"></A>The value of the
target is <I>adjusted.</I> </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>16</FONT></DIV>
<DIV Class="Normal"> <A NAME="I3145"></A><A NAME="I3146"></A>To adjust
the value of a (nonlimited) composite object, the values of the components
of the object are first adjusted in an arbitrary order, and then, if
the object is controlled, Adjust is called. Adjusting the value of an
elementary object has no effect, nor does adjusting the value of a composite
object with no controlled parts. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>17</FONT></DIV>
<DIV Class="Normal"> <A NAME="I3147"></A>For an <FONT FACE="Arial, Helvetica">assignment_statement</FONT>,
after the <FONT FACE="Arial, Helvetica">name</FONT> and <FONT FACE="Arial, Helvetica">expression</FONT>
have been evaluated, and any conversion (including constraint checking)
has been done, an anonymous object is created, and the value is assigned
into it; that is, the assignment operation is applied. (Assignment includes
value adjustment.) The target of the <FONT FACE="Arial, Helvetica">assignment_statement</FONT>
is then finalized. The value of the anonymous object is then assigned
into the target of the <FONT FACE="Arial, Helvetica">assignment_statement</FONT>.
Finally, the anonymous object is finalized. As explained below, the implementation
may eliminate the intermediate anonymous object, so this description
subsumes the one given in <A HREF="RM-5-2.html">5.2</A>, ``<A HREF="RM-5-2.html">Assignment
Statements</A>''. </DIV>
<H4 ALIGN=CENTER>Implementation Requirements</H4>
<DIV Class="Paranum"><FONT SIZE=-2>17.1/1</FONT></DIV>
<DIV Class="Normal"> For an <FONT FACE="Arial, Helvetica">aggregate</FONT>
of a controlled type whose value is assigned, other than by an <FONT FACE="Arial, Helvetica">assignment_statement</FONT>
or a <FONT FACE="Arial, Helvetica">return_statement</FONT>, the implementation
shall not create a separate anonymous object for the <FONT FACE="Arial, Helvetica">aggregate</FONT>.
The aggregate value shall be constructed directly in the target of the
assignment operation and Adjust is not called on the target object. </DIV>
<H4 ALIGN=CENTER>Implementation Permissions</H4>
<DIV Class="Paranum"><FONT SIZE=-2>18</FONT></DIV>
<DIV Class="Normal"> An implementation is allowed to relax the above
rules (for nonlimited controlled types) in the following ways: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>19</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>For an <FONT FACE="Arial, Helvetica">assignment_statement</FONT>
that assigns to an object the value of that same object, the implementation
need not do anything. </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>20</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>For an <FONT FACE="Arial, Helvetica">assignment_statement</FONT>
for a noncontrolled type, the implementation may finalize and assign
each component of the variable separately (rather than finalizing the
entire variable and assigning the entire new value) unless a discriminant
of the variable is changed by the assignment. </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>21</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>For an <FONT FACE="Arial, Helvetica">aggregate</FONT> or
function call whose value is assigned into a target object, the implementation
need not create a separate anonymous object if it can safely create the
value of the <FONT FACE="Arial, Helvetica">aggregate</FONT> or function
call directly in the target object. Similarly, for an <FONT FACE="Arial, Helvetica">assignment_statement</FONT>,
the implementation need not create an anonymous object if the value being
assigned is the result of evaluating a <FONT FACE="Arial, Helvetica">name</FONT>
denoting an object (the source object) whose storage cannot overlap with
the target. If the source object might overlap with the target object,
then the implementation can avoid the need for an intermediary anonymous
object by exercising one of the above permissions and perform the assignment
one component at a time (for an overlapping array assignment), or not
at all (for an assignment where the target and the source of the assignment
are the same object). Even if an anonymous object is created, the implementation
may move its value to the target object as part of the assignment without
re-adjusting so long as the anonymous object has no aliased subcomponents.
</LI></UL>
<HR>
<P><A HREF="RM-TOC.html">Contents</A> <A HREF="RM-0-29.html">Index</A> <A HREF="RM-7-5.html">Previous</A> <A HREF="RM-7-6-1.html">Next</A> <A HREF="RM-TTL.html">Legal</A></P>
</BODY>
</HTML>
|