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 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<TITLE>AARM95 - Formal Private and Derived Types</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="AA-TOC.html">Contents</A> <A HREF="AA-0-29.html">Index</A> <A HREF="AA-12-5.html">Previous</A> <A HREF="AA-12-5-2.html">Next</A></P>
<HR>
<H1> 12.5.1 Formal Private and Derived Types</H1>
<DIV Class="Paranum"><FONT SIZE=-2>1</FONT></DIV>
<DIV Class="Normal"> [The class determined for a formal private type
can be either limited or nonlimited, and either tagged or untagged; no
more specific class is known for such a type. The class determined for
a formal derived type is the derivation class rooted at the ancestor
type.] </DIV>
<H4 ALIGN=CENTER>Syntax</H4>
<DIV Class="Paranum"><FONT SIZE=-2>2</FONT></DIV>
<DIV Class="SyntaxIndented"><FONT FACE="Arial, Helvetica">formal_private_type_definition<A NAME="I4278"></A>
::= </FONT>[[<B>abstract</B>] <B>tagged</B>] [<B>limited</B>] <B>private</B></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>3</FONT></DIV>
<DIV Class="SyntaxIndented"><FONT FACE="Arial, Helvetica">formal_derived_type_definition<A NAME="I4279"></A>
::= </FONT>[<B>abstract</B>] <B>new</B> <A NAME="I4280"></A><FONT FACE="Arial, Helvetica">subtype_mark</FONT> [<B>with</B> <B>private</B>]</DIV>
<H4 ALIGN=CENTER>Legality Rules</H4>
<DIV Class="Paranum"><FONT SIZE=-2>4</FONT></DIV>
<DIV Class="Normal"> If a generic formal type declaration has a <FONT FACE="Arial, Helvetica">known_discriminant_part</FONT>,
then it shall not include a <FONT FACE="Arial, Helvetica">default_expression</FONT>
for a discriminant. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>4.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>Consequently,
a generic formal subtype with a <FONT FACE="Arial, Helvetica">known_discriminant_part</FONT>
is an indefinite subtype, so the declaration of a stand-alone variable
has to provide a constraint on such a subtype, either explicitly, or
by its initial value. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>5</FONT></DIV>
<DIV Class="Normal"> <A NAME="I4281"></A>The <I>ancestor subtype</I>
of a formal derived type is the subtype denoted by the <FONT FACE="Arial, Helvetica">subtype_mark</FONT>
of the <FONT FACE="Arial, Helvetica">formal_derived_type_definition</FONT>.
For a formal derived type declaration, the reserved words <B>with private</B>
shall appear if and only if the ancestor type is a tagged type; in this
case the formal derived type is a private extension of the ancestor type
and the ancestor shall not be a class-wide type. [Similarly, the optional
reserved word <B>abstract</B> shall appear only if the ancestor type
is a tagged type]. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>5.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>We use the term
``ancestor'' here instead of ``parent'' because the actual can be any
descendant of the ancestor, not necessarily a direct descendant. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>6</FONT></DIV>
<DIV Class="Normal"> If the formal subtype is definite, then the actual
subtype shall also be definite. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>6.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>On the other
hand, for an indefinite formal subtype, the actual can be either definite
or indefinite. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>7</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> For a generic formal
derived type with no <FONT FACE="Arial, Helvetica">discriminant_part</FONT>:
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>8</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>If the ancestor subtype is constrained, the actual subtype
shall be constrained, and shall be statically compatible with the ancestor;
</LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>8.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>In other
words, any constraint on the ancestor subtype is considered part of the
``contract.'' </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>9</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>If the ancestor subtype is an unconstrained access or composite
subtype, the actual subtype shall be unconstrained. </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>9.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>This rule ensures
that if a composite constraint is allowed on the formal, one is also
allowed on the actual. If the ancestor subtype is an unconstrained scalar
subtype, the actual is allowed to be constrained, since a scalar constraint
does not cause further constraints to be illegal. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>10</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>If the ancestor subtype is an unconstrained discriminated
subtype, then the actual shall have the same number of discriminants,
and each discriminant of the actual shall correspond to a discriminant
of the ancestor, in the sense of <A HREF="AA-3-7.html">3.7</A>.</LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>10.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>This ensures that
if a discriminant constraint is given on the formal subtype, the corresponding
constraint in the instance will make sense, without additional run-time
checks. This is not necessary for arrays, since the bounds cannot be
overridden in a type extension. An <FONT FACE="Arial, Helvetica">unknown_discriminant_part</FONT>
may be used to relax these matching requirements. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>11</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> The declaration
of a formal derived type shall not have a <FONT FACE="Arial, Helvetica">known_discriminant_part</FONT>.
For a generic formal private type with a <FONT FACE="Arial, Helvetica">known_discriminant_part</FONT>:
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>12</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>The actual type shall be a type with the same number of
discriminants.</LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>13</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>The actual subtype shall be unconstrained.</LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>14</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC>The subtype of each discriminant of the actual type shall
statically match the subtype of the corresponding discriminant of the
formal type. <A NAME="I4282"></A></LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>14.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>We considered defining
the first and third rule to be called ``subtype conformance'' for <FONT FACE="Arial, Helvetica">discriminant_parts</FONT>.
We rejected that idea, because it would require implicit (inherited)
<FONT FACE="Arial, Helvetica">discriminant_parts</FONT>, which seemed
like too much mechanism. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>15</FONT></DIV>
<DIV Class="Normal"> [For a generic formal type with an <FONT FACE="Arial, Helvetica">unknown_discriminant_part</FONT>,
the actual may, but need not, have discriminants, and may be definite
or indefinite.]</DIV>
<H4 ALIGN=CENTER>Static Semantics</H4>
<DIV Class="Paranum"><FONT SIZE=-2>16</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> The class determined
for a formal private type is as follows: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>17</FONT></DIV>
<DIV Class="SyntaxIndented"><I>Type Definition</I> <I>Determined Class</I><BR>
<BR>
<B>limited private</B> the class of all types<BR>
<B>private</B> the class of all nonlimited types<BR>
<B>tagged limited private</B> the class of all tagged types<BR>
<B>tagged private</B> the class of all nonlimited tagged types</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>18</FONT></DIV>
<DIV Class="Normal"> [The presence of the reserved word <B>abstract</B>
determines whether the actual type may be abstract.]</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>19</FONT></DIV>
<DIV Class="Normal"> A formal private or derived type is a private
or derived type, respectively. A formal derived tagged type is a private
extension. [A formal private or derived type is abstract if the reserved
word <B>abstract</B> appears in its declaration.]</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>20</FONT></DIV>
<DIV Class="Normal"> If the ancestor type is a composite type that
is not an array type, the formal type inherits components from the ancestor
type (including discriminants if a new <FONT FACE="Arial, Helvetica">discriminant_part</FONT>
is not specified), as for a derived type defined by a <FONT FACE="Arial, Helvetica">derived_type_definition</FONT>
(see <A HREF="AA-3-4.html">3.4</A>).</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>21/1</FONT></DIV>
<DIV Class="Normal"> {<I><A HREF="defect1.html#8652/0038">8652/0038</A></I>}
For a formal derived type, the predefined operators and inherited user-defined
subprograms are determined by the ancestor type, and are implicitly declared
at the earliest place, if any, within the immediate scope of the formal
type, where the corresponding primitive subprogram of the ancestor is
visible (see <A HREF="AA-7-3-1.html">7.3.1</A>). In an instance, the
copy of such an implicit declaration declares a view of the corresponding
primitive subprogram of the ancestor<U> of the formal derived type</U>,
even if this primitive has been overridden for the actual type. <U>When
the ancestor of the formal derived type is itself a formal type, the
copy of the implicit declaration declares a view of the corresponding
copied operation of the ancestor.</U> [In the case of a formal private
extension, however, the tag of the formal type is that of the actual
type, so if the tag in a call is statically determined to be that of
the formal type, the body executed will be that corresponding to the
actual type.] </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>21.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>The above
rule defining the properties of primitive subprograms in an instance
applies even if the subprogram has been overridden or hidden for the
actual type. This rule is necessary for untagged types, because their
primitive subprograms might have been overridden by operations that are
not subtype-conformant with the operations defined for the class. For
tagged types, the rule still applies, but the primitive subprograms will
dispatch to the appropriate implementation based on the type and tag
of the operands. Even for tagged types, the formal parameter names and
<FONT FACE="Arial, Helvetica">default_expression</FONT>s are determined
by those of the primitive subprograms of the specified ancestor type.
</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>22/1</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em"> For a <U><FONT FACE="Arial, Helvetica">prefix</FONT></U><S>prefix</S>
S that denotes a formal indefinite subtype, the following attribute is
defined: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>23</FONT></DIV>
<DL Class="Hanging"><DT> S'Definite<DD Class="Hanging">
<A NAME="I4283"></A><A NAME="I4284"></A>S'Definite yields True if the
actual subtype corresponding to S is definite; otherwise it yields False.
The value of this attribute is of the predefined type Boolean. </DL>
<DIV Class="Paranum"><FONT SIZE=-2>23.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Discussion: </B>Whether an
actual subtype is definite or indefinite may have a major effect on the
algorithm used in a generic. For example, in a generic I/O package, whether
to use fixed-length or variable-length records could depend on whether
the actual is definite or indefinite. This attribute is essentially a
replacement for the Constrained attribute which is now considered obsolete.
</FONT></DIV>
<DIV Class="NotesHeader"><FONT SIZE=-1>NOTES</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>24</FONT></DIV>
<DIV Class="Notes" Style="margin-bottom: 0.4em"><FONT SIZE=-1>9 In
accordance with the general rule that the actual type shall belong to
the class determined for the formal (see <A HREF="AA-12-5.html">12.5</A>,
``<A HREF="AA-12-5.html">Formal Types</A>''): </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>25</FONT></DIV>
<UL Class="NotesBulleted"><FONT SIZE=-1><LI TYPE=DISC>If the formal type is nonlimited, then so shall be the
actual;</LI></FONT></UL>
<DIV Class="Paranum"><FONT SIZE=-2>26</FONT></DIV>
<UL Class="NotesBulleted"><FONT SIZE=-1><LI TYPE=DISC>For a formal derived type, the actual shall be in the class
rooted at the ancestor subtype. </LI></FONT></UL>
<DIV Class="Paranum"><FONT SIZE=-2>27</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>10 [The actual type can be
abstract only if the formal type is abstract (see <A HREF="AA-3-9-3.html">3.9.3</A>).]
</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>27.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>This is necessary
to avoid contract model problems, since one or more of its primitive
subprograms are abstract; it is forbidden to create objects of the type,
or to declare functions returning the type. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>27.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>On the other
hand, it is OK to pass a non-abstract actual to an abstract formal --
<B>abstract</B> on the formal indicates that the actual might be abstract.
</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>28</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>11 If the formal has a <FONT FACE="Arial, Helvetica">discriminant_part</FONT>,
the actual can be either definite or indefinite. Otherwise, the actual
has to be definite. </FONT></DIV>
<H4 ALIGN=CENTER>Incompatibilities With Ada 83</H4>
<DIV Class="Paranum"><FONT SIZE=-2>28.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><A NAME="I4285"></A>Ada 83 does
not have <FONT FACE="Arial, Helvetica">unknown_discriminant_part</FONT>s,
so it allows indefinite subtypes to be passed to definite formals, and
applies a legality rule to the instance body. This is a contract model
violation. Ada 95 disallows such cases at the point of the instantiation.
The workaround is to add (<>) as the <FONT FACE="Arial, Helvetica">discriminant_part</FONT>
of any formal subtype if it is intended to be used with indefinite actuals.
If that's the intent, then there can't be anything in the generic body
that would require a definite subtype.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>28.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>The check for discriminant subtype
matching is changed from a run-time check to a compile-time check. </FONT></DIV>
<HR>
<P><A HREF="AA-TOC.html">Contents</A> <A HREF="AA-0-29.html">Index</A> <A HREF="AA-12-5.html">Previous</A> <A HREF="AA-12-5-2.html">Next</A> <A HREF="AA-TTL.html">Legal</A></P>
</BODY>
</HTML>
|