File: AA-3-9.html

package info (click to toggle)
ada-reference-manual 20021112web-3
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, lenny, sarge
  • size: 18,652 kB
  • ctags: 8,921
  • sloc: makefile: 52; sh: 20
file content (434 lines) | stat: -rw-r--r-- 30,564 bytes parent folder | download
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
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
    <TITLE>AARM95 - Tagged Types and Type Extensions</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>&nbsp;&nbsp;&nbsp;<A HREF="AA-0-29.html">Index</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-3-8-1.html">Previous</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-3-9-1.html">Next</A></P>
<HR>
<H1> 3.9 Tagged Types and Type Extensions</H1>
<DIV Class="Paranum"><FONT SIZE=-2>1</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;[<A NAME="I2029"></A> <A NAME="I2030"></A><A NAME="I2031"></A><A NAME="I2032"></A><A NAME="I2033"></A>Tagged
types and type extensions support object-oriented programming, based
on inheritance with extension and run-time polymorphism via <I>dispatching
operations</I>. <A NAME="I2034"></A><A NAME="I2035"></A><A NAME="I2036"></A>]</DIV>

<H4 ALIGN=CENTER>Language Design Principles</H4>
<DIV Class="Paranum"><FONT SIZE=-2>1.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>The intended implementation model
is for a tag to be represented as a pointer to a statically allocated
and link-time initialized type descriptor. The type descriptor contains
the address of the code for each primitive operation of the type. It
probably also contains other information, such as might make membership
tests convenient and efficient.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>1.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>The primitive operations of a
tagged type are known at its first freezing point; the type descriptor
is laid out at that point. It contains linker symbols for each primitive
operation; the linker fills in the actual addresses.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>1.c</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>Other implementation models are
possible.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>1.d</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>The rules ensure that ``dangling
dispatching'' is impossible; that is, when a dispatching call is made,
there is always a body to execute. This is different from some other
object-oriented languages, such as Smalltalk, where it is possible to
get a run-time error from a missing method.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>1.e</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>Dispatching calls should be efficient,
and should have a bounded worst-case execution time. This is important
in a language intended for real-time applications. In the intended implementation
model, a dispatching call involves calling indirect through the appropriate
slot in the dispatch table. No complicated &quot;method lookup&quot;
is involved.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>1.f</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>The programmer should have the
choice at each call site of a dispatching operation whether to do a dispatching
call or a statically determined call (i.e. whether the body executed
should be determined at run time or at compile time).</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>1.g</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>The same body should be executed
for a call where the tag is statically determined to be T'Tag as for
a dispatching call where the tag is found at run time to be T'Tag. This
allows one to test a given tagged type with statically determined calls,
with some confidence that run-time dispatching will produce the same
behavior.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>1.h</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>All views of a type should share
the same type descriptor and the same tag.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>1.i</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>The visibility rules determine
what is legal at compile time; they have nothing to do with what bodies
can be executed at run time. Thus, it is possible to dispatch to a subprogram
whose declaration is not visible at the call site. In fact, this is one
of the primary facts that gives object-oriented programming its power.
The subprogram that ends up being dispatched to by a given call might
even be designed long after the call site has been coded and compiled.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>1.j</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>Given that Ada has overloading,
determining whether a given subprogram overrides another is based both
on the names and the type profiles of the operations.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>1.k</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>When a type extension is declared,
if there is any place within its immediate scope where a certain subprogram
of the parent is visible, then a matching subprogram should override.
If there is no such place, then a matching subprogram should be totally
unrelated, and occupy a different slot in the type descriptor. This is
important to preserve the privacy of private parts; when an operation
declared in a private part is inherited, the inherited version can be
overridden only in that private part, in the package body, and in any
children of the package.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>1.l</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>If an implementation shares code
for instances of generic bodies, it should be allowed to share type descriptors
of tagged types declared in the generic body, so long as they are not
extensions of types declared in the specification of the generic unit.
</FONT></DIV>

<H4 ALIGN=CENTER>Static Semantics</H4>
<DIV Class="Paranum"><FONT SIZE=-2>2</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;<A NAME="I2037"></A>A record type or private type
that has the reserved word <B>tagged</B> in its declaration is called
a <I>tagged</I> type. [When deriving from a tagged type, additional components
may be defined. As for any derived type, additional primitive subprograms
may be defined, and inherited primitive subprograms may be overridden.]
<A NAME="I2038"></A><A NAME="I2039"></A>The derived type is called an
<I>extension</I> of the ancestor type, or simply a <I>type extension</I>.
<A NAME="I2040"></A><A NAME="I2041"></A><A NAME="I2042"></A>Every type
extension is also a tagged type, and is either a <I>record extension</I>
or a <I>private extension</I> of some other tagged type. A record extension
is defined by a <FONT FACE="Arial, Helvetica">derived_type_definition</FONT>
with a <FONT FACE="Arial, Helvetica">record_extension_part</FONT>. A
private extension, which is a partial view of a record extension, can
be declared in the visible part of a package (see <A HREF="AA-7-3.html">7.3</A>)
or in a generic formal part (see <A HREF="AA-12-5-1.html">12.5.1</A>).
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>2.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Glossary entry: </B>The objects
of a tagged type have a run-time type tag, which indicates the specific
type with which the object was originally created. An operand of a class-wide
tagged type can be used in a dispatching call; the tag indicates which
subprogram body to invoke. Nondispatching calls, in which the subprogram
body to invoke is determined at compile time, are also allowed. Tagged
types may be extended with additional components.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>2.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>If a tagged
type is declared other than in a <FONT FACE="Arial, Helvetica">package_specification</FONT>,
it is impossible to add new primitive subprograms for that type, although
it can inherit primitive subprograms, and those can be overridden. If
the user incorrectly thinks a certain subprogram is primitive when it
is not, and tries to call it with a dispatching call, an error message
will be given at the call site.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>2.c</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>Note that the accessibility rules
imply that a tagged type declared in a library <FONT FACE="Arial, Helvetica">package_specification</FONT>
cannot be extended in a nested subprogram or task body. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>3</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;<A NAME="I2043"></A>An object of a tagged type
has an associated (run-time) <I>tag</I> that identifies the specific
tagged type used to create the object originally. [ The tag of an operand
of a class-wide tagged type <I>T</I>'Class controls which subprogram
body is to be executed when a primitive subprogram of type <I>T</I> is
applied to the operand (see <A HREF="AA-3-9-2.html">3.9.2</A>); <A NAME="I2044"></A>using
a tag to control which body to execute is called <I>dispatching</I>.]
<A NAME="I2045"></A><A NAME="I2046"></A><A NAME="I2047"></A><A NAME="I2048"></A></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>4</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;The tag of a specific tagged type identifies the
<FONT FACE="Arial, Helvetica">full_type_declaration</FONT> of the type.
If a declaration for a tagged type occurs within a <FONT FACE="Arial, Helvetica">generic_package_declaration</FONT>,
then the corresponding type declarations in distinct instances of the
generic package are associated with distinct tags. For a tagged type
that is local to a generic package body, the language does not specify
whether repeated instantiations of the generic body result in distinct
tags. </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>4.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>This eases generic
code sharing.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>4.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Implementation Note: </B>The
language does not specify whether repeated elaborations of the same <FONT FACE="Arial, Helvetica">full_type_declaration</FONT>
correspond to distinct tags. In most cases, we expect that all elaborations
will correspond to the same tag, since the tag will frequently be the
address (or index) of a statically allocated type descriptor. However,
with shared generics, the type descriptor might have to be allocated
on a per-instance basis, which in some implementation models implies
per-elaboration of the instantiation. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>5</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em">&nbsp;&nbsp;&nbsp;The following language-defined
library package exists: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>6</FONT></DIV>
<DIV Class="Examples"><TT><A NAME="I2049"></A><A NAME="I2050"></A><A NAME="I2051"></A><B>package</B>&nbsp;Ada.Tags&nbsp;<B>is</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>type</B>&nbsp;<A NAME="I2052"></A><A NAME="I2053"></A>Tag&nbsp;<B>is</B>&nbsp;<B>private</B>;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>7</FONT></DIV>
<DIV Class="Examples"><TT>&nbsp;&nbsp;&nbsp;&nbsp;<B>function</B>&nbsp;<A NAME="I2054"></A><A NAME="I2055"></A>Expanded_Name(T&nbsp;:&nbsp;Tag)&nbsp;<B>return</B>&nbsp;String;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>function</B>&nbsp;<A NAME="I2056"></A><A NAME="I2057"></A>External_Tag(T&nbsp;:&nbsp;Tag)&nbsp;<B>return</B>&nbsp;String;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;<B>function</B>&nbsp;<A NAME="I2058"></A><A NAME="I2059"></A>Internal_Tag(External&nbsp;:&nbsp;String)&nbsp;<B>return</B>&nbsp;Tag;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>8</FONT></DIV>
<DIV Class="Examples"><TT>&nbsp;&nbsp;&nbsp;&nbsp;<A NAME="I2060"></A>Tag_Error&nbsp;:&nbsp;<B>exception</B>;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>9</FONT></DIV>
<DIV Class="Examples"><TT><B>private</B><BR>
&nbsp;&nbsp;&nbsp;...&nbsp;--&nbsp;<I>not&nbsp;specified&nbsp;by&nbsp;the&nbsp;language</I><BR>
<B>end</B>&nbsp;Ada.Tags;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>9.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>Tag is a nonlimited,
definite subtype, because it needs the equality operators, so that tag
checking makes sense. Also, equality, assignment, and object declaration
are all useful capabilities for this subtype.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>9.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>For an object X and a type T,
``X'Tag = T'Tag'' is not needed, because a membership test can be used.
However, comparing the tags of two objects cannot be done via membership.
This is one reason to allow equality for type Tag. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>10</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;&nbsp;The function Expanded_Name returns the full expanded
name of the first subtype of the specific type identified by the tag,
in upper case, starting with a root library unit. The result is implementation
defined if the type is declared within an unnamed <FONT FACE="Arial, Helvetica">block_statement</FONT>.
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>10.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>To be honest: </B>This name,
as well as each <FONT FACE="Arial, Helvetica">prefix</FONT> of it, does
not denote a <FONT FACE="Arial, Helvetica">renaming_declaration</FONT>.
</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>10.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Implementation defined: </B>The
result of Tags.Expanded_Name for types declared within an unnamed <FONT FACE="Arial, Helvetica">block_statement</FONT>.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>11</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;&nbsp;The function External_Tag returns a string to
be used in an external representation for the given tag. The call External_Tag(S'Tag)
is equivalent to the <FONT FACE="Arial, Helvetica">attribute_reference</FONT>
S'External_Tag (see <A HREF="AA-13-3.html">13.3</A>). </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>11.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>It might seem redundant
to provide both the function External_Tag and the attribute External_Tag.
The function is needed because the attribute can't be applied to values
of type Tag. The attribute is needed so that it can be specifiable via
an <FONT FACE="Arial, Helvetica">attribute_definition_clause</FONT>.
</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>12</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;&nbsp;The function Internal_Tag returns the tag that
corresponds to the given external tag, or raises Tag_Error if the given
string is not the external tag for any specific type of the partition.</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>13</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;&nbsp;For every subtype S of a tagged type <I>T</I>
(specific or class-wide), the following attributes are defined: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>14</FONT></DIV>
<DL Class="Hanging"><DT>&nbsp;&nbsp;&nbsp;&nbsp;S'Class<DD Class="Hanging">
<A NAME="I2061"></A><A NAME="I2062"></A>S'Class denotes a subtype of
the class-wide type (called <I>T</I>'Class in this International Standard)
for the class rooted at <I>T</I> (or if S already denotes a class-wide
subtype, then S'Class is the same as S).</DL>
<DIV Class="Paranum"><FONT SIZE=-2>15</FONT></DIV>
<DL Class="Hanging"><DD Class ="Hanging"><A NAME="I2063"></A><A NAME="I2064"></A>S'Class
is unconstrained. However, if S is constrained, then the values of S'Class
are only those that when converted to the type <I>T</I> belong to S.
</DL>
<DIV Class="Paranum"><FONT SIZE=-2>15.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>This attribute
is defined for both specific and class-wide subtypes. The definition
is such that S'Class'Class is the same as S'Class.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>15.b</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1>Note that if S is constrained,
S'Class is only partially constrained, since there might be additional
discriminants added in descendants of <I>T</I> which are not constrained.
</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>15.c</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>The Class attribute
is not defined for untagged subtypes (except for incomplete types and
private types whose full view is tagged -- see <A HREF="AA-3-10-1.html">3.10.1</A>
and <A HREF="AA-7-3-1.html">7.3.1</A>) so as to preclude implicit conversion
in the absence of run-time type information. If it were defined for untagged
subtypes, it would correspond to the concept of universal types provided
for the predefined numeric classes. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>16</FONT></DIV>
<DL Class="Hanging"><DT>&nbsp;&nbsp;&nbsp;&nbsp;S'Tag<DD Class="Hanging">
<A NAME="I2065"></A><A NAME="I2066"></A>S'Tag denotes the tag of the
type <I>T</I> (or if <I>T</I> is class-wide, the tag of the root type
of the corresponding class). The value of this attribute is of type Tag.
</DL>
<DIV Class="Paranum"><FONT SIZE=-2>16.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>S'Class'Tag equals
S'Tag, to avoid generic contract model problems when S'Class is the actual
type associated with a generic formal derived type.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>17</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;&nbsp;Given a <FONT FACE="Arial, Helvetica">prefix</FONT>
X that is of a class-wide tagged type [(after any implicit dereference)],
the following attribute is defined: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>18</FONT></DIV>
<DL Class="Hanging"><DT>&nbsp;&nbsp;&nbsp;&nbsp;X'Tag<DD Class="Hanging">
<A NAME="I2067"></A><A NAME="I2068"></A>X'Tag denotes the tag of X. The
value of this attribute is of type Tag. </DL>
<DIV Class="Paranum"><FONT SIZE=-2>18.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>X'Tag is not defined
if X is of a specific type. This is primarily to avoid confusion that
might result about whether the Tag attribute should reflect the tag of
the type of X, or the tag of X. No such confusion is possible if X is
of a class-wide type. </FONT></DIV>

<H4 ALIGN=CENTER>Dynamic Semantics</H4>
<DIV Class="Paranum"><FONT SIZE=-2>19</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em">&nbsp;&nbsp;&nbsp;&nbsp;The tag associated
with an object of a tagged type is determined as follows: </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>20</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC><A NAME="I2069"></A>The tag of a stand-alone object, a
component, or an <FONT FACE="Arial, Helvetica">aggregate</FONT> of a
specific tagged type <I>T</I> identifies <I>T</I>. </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>20.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Discussion: </B>The tag of
a formal parameter of type <I>T</I> is not necessarily the tag of <I>T</I>,
if, for example, the actual was a type conversion. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>21</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC><A NAME="I2070"></A>The tag of an object created by an
allocator for an access type with a specific designated tagged type <I>T</I>,
identifies <I>T</I>. </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>21.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Discussion: </B>The tag of
an object designated by a value of such an access type might not be <I>T</I>,
if, for example, the access value is the result of a type conversion.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>22</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC><A NAME="I2071"></A>The tag of an object of a class-wide
tagged type is that of its initialization expression. </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>22.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Ramification: </B>The tag of
an object (even a class-wide one) cannot be changed after it is initialized,
since a ``class-wide'' <FONT FACE="Arial, Helvetica">assignment_statement</FONT>
raises Constraint_Error if the tags don't match, and a ``specific'' <FONT FACE="Arial, Helvetica">assignment_statement</FONT>
does not affect the tag. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>23</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC><A NAME="I2072"></A>The tag of the result returned by a
function whose result type is a specific tagged type <I>T</I> identifies
<I>T</I>. </LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>23.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Implementation Note: </B>This
requires a run-time check for limited tagged types, since they are returned
&quot;by-reference.&quot;  For a nonlimited type, a new anonymous object
with the appropriate tag is created as part of the function return, and
then assigned the value of the return expression. See <A HREF="AA-6-5.html">6.5</A>,
``<A HREF="AA-6-5.html">Return Statements</A>''. </FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>24</FONT></DIV>
<UL Class="Bulleted"><LI TYPE=DISC><A NAME="I2073"></A>The tag of the result returned by a
function with a class-wide result type is that of the return expression.
</LI></UL>
<DIV Class="Paranum"><FONT SIZE=-2>25</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;&nbsp;<A NAME="I2074"></A>The tag is preserved by type
conversion and by parameter passing. The tag of a value is the tag of
the associated object (see <A HREF="AA-6-2.html">6.2</A>).</DIV>

<H4 ALIGN=CENTER>Implementation Permissions</H4>
<DIV Class="Paranum"><FONT SIZE=-2>26</FONT></DIV>
<DIV Class="Normal">&nbsp;&nbsp;&nbsp;&nbsp;The implementation of the functions in Ada.Tags
may raise Tag_Error if no specific type corresponding to the tag passed
as a parameter exists in the partition at the time the function is called.
</DIV>
<DIV Class="Paranum"><FONT SIZE=-2>26.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><B>Reason: </B>In most implementations,
repeated elaborations of the same <FONT FACE="Arial, Helvetica">type_declaration</FONT>
will all produce the same tag. In such an implementation, Tag_Error will
be raised in cases where the internal or external tag was passed from
a different partition. However, some implementations might create a new
tag value at run time for each elaboration of a <FONT FACE="Arial, Helvetica">type_declaration</FONT>.
In that case, Tag_Error could also be raised if the created type no longer
exists because the subprogram containing it has returned, for example.
We don't require the latter behavior; hence the word ``may'' in this
rule. </FONT></DIV>
<DIV Class="NotesHeader"><FONT SIZE=-1>NOTES</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>27</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>62&nbsp;&nbsp;A type declared with the
reserved word <B>tagged</B> should normally be declared in a <FONT FACE="Arial, Helvetica">package_specification</FONT>,
so that new primitive subprograms can be declared for it.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>28</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>63&nbsp;&nbsp;Once an object has been
created, its tag never changes.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>29</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>64&nbsp;&nbsp;Class-wide types are defined
to have unknown discriminants (see <A HREF="AA-3-7.html">3.7</A>). This
means that objects of a class-wide type have to be explicitly initialized
(whether created by an <FONT FACE="Arial, Helvetica">object_declaration</FONT>
or an <FONT FACE="Arial, Helvetica">allocator</FONT>), and that <FONT FACE="Arial, Helvetica">aggregate</FONT>s
have to be explicitly qualified with a specific type when their expected
type is class-wide.</FONT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>30</FONT></DIV>
<DIV Class="Notes"><FONT SIZE=-1>65&nbsp;&nbsp;If S denotes an untagged
private type whose full type is tagged, then S'Class is also allowed
before the full type definition, but only in the private part of the
package in which the type is declared (see <A HREF="AA-7-3-1.html">7.3.1</A>).
Similarly, the Class attribute is defined for incomplete types whose
full type is tagged, but only within the library unit in which the incomplete
type is declared (see <A HREF="AA-3-10-1.html">3.10.1</A>).</FONT></DIV>

<H4 ALIGN=CENTER>Examples</H4>
<DIV Class="Paranum"><FONT SIZE=-2>31</FONT></DIV>
<DIV Class="Normal" Style="margin-bottom: 0.4em">&nbsp;&nbsp;&nbsp;&nbsp;<I>Examples of
tagged record types:</I> </DIV>
<DIV Class="Paranum"><FONT SIZE=-2>32</FONT></DIV>
<DIV Class="Examples"><TT><B>type</B>&nbsp;Point&nbsp;<B>is&nbsp;tagged</B><BR>
&nbsp;&nbsp;<B>record</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;X,&nbsp;Y&nbsp;:&nbsp;Real&nbsp;:=&nbsp;0.0;<BR>
&nbsp;&nbsp;<B>end&nbsp;record</B>;</TT></DIV>
<DIV Class="Paranum"><FONT SIZE=-2>33</FONT></DIV>
<DIV Class="Examples"><TT><B>type</B>&nbsp;Expression&nbsp;<B>is&nbsp;tagged&nbsp;null&nbsp;record</B>;<BR>
&nbsp;&nbsp;<I>--&nbsp;Components&nbsp;will&nbsp;be&nbsp;added&nbsp;by&nbsp;each&nbsp;extension</I></TT></DIV>

<H4 ALIGN=CENTER>Extensions to Ada 83</H4>
<DIV Class="Paranum"><FONT SIZE=-2>33.a</FONT></DIV>
<DIV Class="Annotations"><FONT SIZE=-1><A NAME="I2075"></A>Tagged types
are a new concept. </FONT></DIV>

<HR>
<P><A HREF="AA-TOC.html">Contents</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-0-29.html">Index</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-3-8-1.html">Previous</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-3-9-1.html">Next</A>&nbsp;&nbsp;&nbsp;<A HREF="AA-TTL.html">Legal</A></P>
</BODY>
</HTML>