13.3 Operational and Representation AttributesRepresentation Attributes
1/1
{
8652/0009}
{
AI95-00137-01}
[
The values of certain implementation-dependent
characteristics can be obtained by interrogating appropriate
operational
or representation attributes.
Some of these
attributes are specifiable via an
attribute_definition_clause.]
Language Design Principles
1.a
In general, the meaning of a given attribute
should not depend on whether the attribute was specified via an
attribute_definition_clause,
or chosen by default by the implementation.
Syntax
2
Name Resolution Rules
3
4
For an
attribute_definition_clause
that specifies an attribute that denotes a value or an object, the expected
type for the expression or
name
is that of the attribute.
For an
attribute_definition_clause
that specifies an attribute that denotes a subprogram, the expected profile
for the
name
is the profile required for the attribute. For an
attribute_definition_clause
that specifies an attribute that denotes some other kind of entity, the
name shall
resolve to denote an entity of the appropriate kind.
4.a
Ramification: For example, the Size attribute
is of type universal_integer. Therefore, the expected type for
Y in “for X'Size use Y;” is universal_integer,
which means that Y can be of any integer type.
4.b
Discussion: For attributes that denote
subprograms, the required profile is indicated separately for the individual
attributes.
4.c
Ramification:
For an
attribute_definition_clause
with a
name,
the
name need
not statically denote the entity it denotes. For example, the following
kinds of things are allowed:
4.d
for Some_Access_Type'Storage_Pool use Storage_Pool_Array(I);
for Some_Type'Read use Subprogram_Pointer.all;
Legality Rules
5/3
5.a
Discussion: For each specifiable attribute,
we generally say something like, “The ... attribute may be specified
for ... via an
attribute_definition_clause.”
5.b
The above wording allows for T'Class'Alignment,
T'Class'Size, T'Class'Input, and T'Class'Output to be specifiable.
5.c
A specifiable attribute is not necessarily specifiable
for all entities for which it is defined. For example, one is allowed
to ask T'Component_Size for an array subtype T, but “for
T'Component_Size use ...” is only allowed if T is a first
subtype, because Component_Size is a type-related aspect.
6
For an
attribute_definition_clause
that specifies an attribute that denotes a subprogram, the profile shall
be mode conformant with the one required for the attribute, and the convention
shall be Ada. Additional requirements are defined for particular attributes.
6.a
Ramification:
This implies, for example, that if one writes:
6.b
for T'Read use R;
6.c
R has to be a procedure with two parameters
with the appropriate subtypes and modes as shown in
13.13.2.
Static Semantics
7/2
7.a
8
A
storage
element is an addressable element of storage in the machine.
A
word is the largest amount of storage that can be conveniently
and efficiently manipulated by the hardware, given the implementation's
run-time model. A word consists of an integral number of storage elements.
8.a
Discussion: A storage element is not
intended to be a single bit, unless the machine can efficiently address
individual bits.
8.b
Ramification: For example, on a machine
with 8-bit storage elements, if there exist 32-bit integer registers,
with a full set of arithmetic and logical instructions to manipulate
those registers, a word ought to be 4 storage elements — that is,
32 bits.
8.c
Discussion: The “given the implementation's
run-time model” part is intended to imply that, for example, on
an 80386 running MS-DOS, the word might be 16 bits, even though the hardware
can support 32 bits.
8.d
A word is what ACID refers to as a “natural
hardware boundary”.
8.e
Storage elements may, but need not be, independently
addressable (see
9.10, “
Shared
Variables”). Words are expected to be independently addressable.
8.1/3
{
AI95-00133-01}
{
AI05-0092-1}
A machine scalar is
an amount of storage that can be conveniently and efficiently loaded,
stored, or operated upon by the hardware. Machine scalars consist of
an integral number of storage elements. The set of machine scalars is
implementation defined, but includes must
include at least the storage element
and the word. Machine scalars are used to interpret component_clauses
when the nondefault bit ordering applies.
8.e.1/2
Implementation defined:
The set of machine scalars.
8.f/3
Ramification: {
AI05-0092-1}
A single storage element is a machine scalar in
all Ada implementations. Similarly, a word is a machine scalar in all
implementations (although it might be the same as a storage element).
An implementation may define other machine scalars that make sense on
the target (a half-word, for instance).
9/3
{
8652/0009}
{
AI95-00137-01}
{
AI05-0191-1}
The following representation attributes are defined:
Address, Alignment, Size, Storage_Size, and
Component_Size,
Has_Same_Storage, and Overlaps_Storage. The
following attributes are defined:
10/1
For a
prefix prefix
X that denotes an object, program unit, or label:
11
X'Address
Denotes the address of the first
of the storage elements allocated to X. For a program unit or label,
this value refers to the machine code associated with the corresponding
body or
statement.
The value of this attribute is of type System.Address.
11.a
Ramification: Here, the “first
of the storage elements” is intended to mean the one with the lowest
address; the endianness of the machine doesn't matter.
11.1/3
{
AI05-0095-1}
The prefix of X'Address shall not statically denote
a subprogram that has convention Intrinsic. X'Address raises Program_Error
if X denotes a subprogram that has convention Intrinsic.
12
Address
may be specified for stand-alone objects and for program units via an
attribute_definition_clause.
12.a
Ramification: Address is not allowed
for enumeration literals, predefined operators, derived task types, or
derived protected types, since they are not program units.
12.b/3
Address is not allowed
for intrinsic subprograms, either. That can be checked statically unless
the prefix is a generic formal subprogram and the attribute reference
is in the body of a generic unit. We define that case to raise Program_Error,
in order that the compiler does not have to build a wrapper for intrinsic
subprograms.
12.c
The validity of a given address depends on the
run-time model; thus, in order to use Address clauses correctly, one
needs intimate knowledge of the run-time model.
12.d/3
{
AI05-0229-1}
If the Address of an object is specified, any explicit or implicit initialization
takes place as usual, unless
the a
pragma
Import
aspect is also specified for the
object (in which case any necessary initialization is presumably done
in the foreign language).
12.e
Any compilation unit containing an
attribute_reference
of a given type depends semantically on the declaration of the package
in which the type is declared, even if not mentioned in an applicable
with_clause
— see
10.1.1. In this case, it means
that if a compilation unit contains X'Address, then it depends on the
declaration of System. Otherwise, the fact that the value of Address
is of a type in System wouldn't make sense; it would violate the “legality
determinable via semantic dependences” Language Design Principle.
12.f
AI83-00305 — If X is a task type, then
within the body of X, X denotes the current task object; thus, X'Address
denotes the object's address.
12.g
12.h
If X is not allocated on a storage element boundary,
X'Address points at the first of the storage elements that contains any
part of X. This is important for the definition of the Position attribute
to be sensible.
12.i/3
Aspect Description
for Address: Machine
address of an entity.
Erroneous Execution
13/3
{
AI05-0009-1}
If an Address is specified, it is the programmer's
responsibility to ensure that the address is valid
and appropriate for the entity and its use; otherwise, program
execution is erroneous.
13.a
Discussion: “Appropriate
for the entity and its use” covers cases such as misaligned addresses,
read-only code addresses for variable data objects (and non-executable
data addresses for code units), and addresses which would force objects
that are supposed to be independently addressable to not be. Such addresses
may be “valid” as they designate locations that are accessible
to the program, but the program execution is still erroneous (meaning
that implementations do not have to worry about these cases).
Implementation Advice
14
For an array X, X'Address should point at the first
component of the array, and not at the array bounds.
14.a.1/2
Implementation Advice:
For an array X, X'Address should point
at the first component of the array rather than the array bounds.
14.a
Ramification: On the other hand, we have
no advice to offer about discriminants and tag fields; whether or not
the address points at them is not specified by the language. If discriminants
are stored separately, then the Position of a discriminant might be negative,
or might raise an exception.
15
The recommended level of support
for the Address attribute is:
16
X'Address should
produce a useful result if X is an object that is aliased or of a by-reference
type, or is an entity whose Address has been specified.
16.a
Reason: Aliased objects are the ones
for which the Unchecked_Access attribute is allowed; hence, these have
to be allocated on an addressable boundary anyway. Similar considerations
apply to objects of a by-reference type.
16.b
An implementation need not go to any trouble
to make Address work in other cases. For example, if an object X is not
aliased and not of a by-reference type, and the implementation chooses
to store it in a register, X'Address might return System.Null_Address
(assuming registers are not addressable). For a subprogram whose calling
convention is Intrinsic, or for a package, the implementation need not
generate an out-of-line piece of code for it.
17
An implementation should support Address clauses
for imported subprograms.
18/2
This paragraph
was deleted.{
AI95-00291-02}
Objects (including subcomponents) that are aliased
or of a by-reference type should be allocated on storage element boundaries.
18.a/2
This paragraph
was deleted.Reason: This is necessary
for the Address attribute to be useful (since First_Bit and Last_Bit
apply only to components). Implementations generally need to do this
anyway, for tasking to work properly.
19
If the Address of an object is specified, or it
is imported or exported, then the implementation should not perform optimizations
based on assumptions of no aliases.
19.a/2
Implementation Advice:
The recommended level of support for
the Address attribute should be followed.
20
2 The specification of a link name
with
the Link_Name aspect in a pragma
Export (see
B.1) for a subprogram or
object is an alternative to explicit specification of its link-time address,
allowing a link-time directive to place the subprogram or object within
memory.
21
3 The rules for the Size attribute imply,
for an aliased object X, that if X'Size = Storage_Unit, then X'Address
points at a storage element containing all of the bits of X, and only
the bits of X.
Wording Changes from Ada 83
21.a
21.b
21.c
Wording Changes from Ada 2005
21.c.1/3
Language Design Principles
21.d
By default, the Alignment of a subtype should
reflect the “natural” alignment for objects of the subtype
on the machine. The Alignment, whether specified or default, should be
known at compile time, even though Addresses are generally not known
at compile time. (The generated code should never need to check at run
time the number of zero bits at the end of an address to determine an
alignment).
21.e
There are two symmetric purposes of Alignment
clauses, depending on whether or not the implementation has control over
object allocation. If the implementation allocates an object, the implementation
should ensure that the Address and Alignment are consistent with each
other. If something outside the implementation allocates an object, the
implementation should be allowed to assume that the Address and Alignment
are consistent, but should not assume stricter alignments than that.
Static Semantics
22/2
23/2
X'Alignment
{
AI95-00291-02}
The value of this attribute is of type universal_integer,
and nonnegative; zero means that the object is not necessarily aligned
on a storage element boundary. If X'Alignment is not zero, then X is
aligned on a storage unit boundary and X'Address The
Address of an object that is allocated under control of the implementation
is an integral multiple of
X'Alignment the
Alignment of the object (that is, the Address modulo the Alignment
is zero).
The offset of a record component is a
multiple of the Alignment of the component. For an object that is not
allocated under control of the implementation (that is, one that is imported,
that is allocated by a user-defined allocator, whose Address has been
specified, or is designated by an access value returned by an instance
of Unchecked_Conversion), the implementation may assume that the Address
is an integral multiple of its Alignment. The implementation shall not
assume a stricter alignment.
24/2
This paragraph
was deleted.{
AI95-00291-02}
The value of this attribute is of type universal_integer,
and nonnegative; zero means that the object is not necessarily aligned
on a storage element boundary.
24.a
Ramification: The Alignment is passed
by an
allocator
to the Allocate operation; the implementation has to choose a value such
that if the address returned by Allocate is aligned as requested, the
generated code can correctly access the object.
24.b
The above mention of “modulo” is
referring to the "mod" operator declared in System.Storage_Elements;
if X mod N = 0, then X is by definition aligned on an N-storage-element
boundary.
25/2
{
AI95-00291-02}
Alignment
may be specified for
first subtypes and
[stand-alone] objects via an
attribute_definition_clause;
the expression of such a clause shall be static, and its value nonnegative.
If
the Alignment of a subtype is specified, then the Alignment of an object
of the subtype is at least as strict, unless the object's Alignment is
also specified. The Alignment of an object created by an allocator is
that of the designated subtype.
25.a/3
Aspect Description
for Alignment (object): Alignment
of an object.
26/2
This paragraph
was deleted.{
AI95-00247-01}
If an Alignment is specified for a composite subtype
or object, this Alignment shall be equal to the least common multiple
of any specified Alignments of the subcomponent subtypes, or an integer
multiple thereof.
26.1/2
26.2/2
S'Alignment
{
AI95-00291-02}
The value of this
attribute is of type universal_integer, and nonnegative.
26.3/2
{
AI95-00051-02}
{
AI95-00291-02}
For an object X of subtype S, if S'Alignment is
not zero, then X'Alignment is a nonzero integral multiple of S'Alignment
unless specified otherwise by a representation item.
26.4/2
{
AI95-00291-02}
Alignment
may be specified for first subtypes via an attribute_definition_clause;
the expression of such a clause shall be static, and its value nonnegative.
26.a/3
Aspect Description
for Alignment (subtype): Alignment
of a subtype.
Erroneous Execution
27
Program execution is erroneous
if an Address clause is given that conflicts with the Alignment.
27.a
Ramification: The user has to either
give an Alignment clause also, or else know what Alignment the implementation
will choose by default.
28/2
{
AI95-00051-02}
{
AI95-00291-02}
For If
the Alignment is specified for an object that is not allocated
under control of the implementation, execution is erroneous if the object
is not aligned according to
its the
Alignment.
Implementation Advice
28.1/3
{
AI05-0116-1}
For any tagged specific subtype S, S'Class'Alignment
should equal S'Alignment.
28.a/3
Reason: A tagged
object should never be less aligned than the alignment of the type of
its view, so for a class-wide type T'Class, the alignment should be no
greater than that of any type covered by T'Class. If the implementation
only supports alignments that are required by the recommended level of
support (and this is most likely), then the alignment of any covered
type has to be the same or greater than that of T — which leaves
the only reasonable value of T'Class'Alignment being T'Alignment. Thus
we recommend this, but don't require it so that in the unlikely case
that the implementation does support smaller alignments for covered types,
it can select a smaller value for T'Class'Alignment.
28.a.1/3
Implementation Advice:
For any tagged specific subtype S,
S'Class'Alignment should equal S'Alignment.
29
The recommended level of support
for the Alignment attribute for subtypes is:
30/2
{
AI95-00051-02}
An implementation should support
an Alignment clause
for a discrete type, fixed point type, record type, or array type, specifying
an Alignment value that is zero or a power of two specified
Alignments that are factors and multiples of the number of storage elements
per word, subject to the following:
31/2
{
AI95-00051-02}
An implementation need not support
an Alignment
clause for a signed integer type specifying an Alignment greater than
the largest Alignment value that is ever chosen by default by the implementation
for any signed integer type. A corresponding limitation may be imposed
for modular integer types, fixed point types, enumeration types, record
types, and array types specified Alignments
for combinations of Sizes and Alignments that cannot be easily loaded
and stored by available machine instructions.
32/2
{
AI95-00051-02}
An implementation need not support
a nonconfirming
Alignment clause which could enable the creation of an object of an elementary
type which cannot be easily loaded and stored by available machine instructions. specified
Alignments that are greater than the maximum Alignment the implementation
ever returns by default.
32.1/2
{
AI95-00291-02}
An implementation need not support an Alignment
specified for a derived tagged type which is not a multiple of the Alignment
of the parent type. An implementation need not support a nonconfirming
Alignment specified for a derived untagged by-reference type.
32.a/2
Ramification: {
AI95-00291-02}
There is no recommendation to support any nonconfirming
Alignment clauses for types not mentioned above. Remember that 13.1
requires support for confirming Alignment clauses for all types.
32.b/3
Implementation Note:
{
AI05-0116-1}
An implementation that tries to support other alignments
for derived tagged types will need to allow inherited subprograms to
be passed objects that are less aligned than expected by the parent subprogram
and type. This is unlikely to work if alignment has any effect on code
selection. Similar issues arise for untagged derived types whose parameters
are passed by reference.
33
The
recommended level of support for the Alignment attribute for objects
is:
34/2
This paragraph
was deleted.{
AI95-00291-02}
Same as above, for subtypes, but in addition:
35
For stand-alone library-level objects of statically
constrained subtypes, the implementation should support all Alignments
supported by the target linker. For example, page alignment is likely
to be supported for such objects, but not for subtypes.
35.1/2
{
AI95-00291-02}
For other objects, an implementation should at
least support the alignments supported for their subtype, subject to
the following:
35.2/2
{
AI95-00291-02}
An implementation need not support Alignments specified
for objects of a by-reference type or for objects of types containing
aliased subcomponents if the specified Alignment is not a multiple of
the Alignment of the subtype of the object.
35.a/2
Implementation Advice:
The recommended level of support for
the Alignment attribute should be followed.
36
4 Alignment is a subtype-specific attribute.
37/2
This paragraph was
deleted.5 {
AI95-00247-01}
The Alignment of a composite object is always equal
to the least common multiple of the Alignments of its components, or
a multiple thereof.
37.a/2
This paragraph
was deleted.Discussion: For default
Alignments, this follows from the semantics of Alignment. For specified
Alignments, it follows from a Legality Rule stated above.
38/3
38.a
Discussion: Most objects are allocated
by the implementation; for these, the implementation obeys the Alignment.
The implementation is of course allowed to make an object more
aligned than its Alignment requires — an object whose Alignment
is 4 might just happen to land at an address that's a multiple of 4096.
For formal parameters, the implementation might want to force an Alignment
stricter than the parameter's subtype. For example, on some systems,
it is customary to always align parameters to 4 storage elements.
38.b
Hence, one might initially assume that the implementation
could evilly make all Alignments 1 by default, even though integers,
say, are normally aligned on a 4-storage-element boundary. However, the
implementation cannot get away with that — if the Alignment is
1, the generated code cannot assume an Alignment of 4, at least not for
objects allocated outside the control of the implementation.
38.c
Of course implementations can assume anything
they can prove, but typically an implementation will be unable to prove
much about the alignment of, say, an imported object. Furthermore, the
information about where an address “came from” can be lost
to the compiler due to separate compilation.
38.d/3
{
AI95-00114-01}
{
AI05-0229-1}
The Alignment of an object that is a component of a packed composite
object will usually be 0, to indicate that the component is not necessarily
aligned on a storage element boundary. For a subtype, an Alignment of
0 means that objects of the subtype are not normally aligned on a storage
element boundary at all. For example, an implementation might choose
to make Component_Size be
1 0
for an array of Booleans, even when
the aspect pragma
Pack has not been specified for the array. In this case, Boolean'Alignment
would be 0. (In the presence of tasking, this would in general be feasible
only on a machine that had atomic test-bit and set-bit instructions.)
38.e
If the machine has no particular natural alignments,
then all subtype Alignments will probably be 1 by default.
38.f
Specifying an Alignment of 0 in an
attribute_definition_clause
does not require the implementation to do anything (except return 0 when
the Alignment is queried). However, it might be taken as advice on some
implementations.
38.g
It is an error for an Address clause to disobey
the object's Alignment. The error cannot be detected at compile time,
in general, because the Address is not necessarily known at compile time
(and is almost certainly not static). We do not require a run-time check,
since efficiency seems paramount here, and Address clauses are treading
on thin ice anyway. Hence, this misuse of Address clauses is just like
any other misuse of Address clauses — it's erroneous.
38.h
A type extension can have a stricter Alignment
than its parent. This can happen, for example, if the Alignment of the
parent is 4, but the extension contains a component with Alignment 8.
The Alignment of a class-wide type or object will have to be the maximum
possible Alignment of any extension.
38.i
The recommended level of support for the Alignment
attribute is intended to reflect a minimum useful set of capabilities.
An implementation can assume that all Alignments are multiples of each
other — 1, 2, 4, and 8 might be the only supported Alignments for
subtypes. An Alignment of 3 or 6 is unlikely to be useful. For objects
that can be allocated statically, we recommend that the implementation
support larger alignments, such as 4096. We do not recommend such large
alignments for subtypes, because the maximum subtype alignment will also
have to be used as the alignment of stack frames, heap objects, and class-wide
objects. Similarly, we do not recommend such large alignments for stack-allocated
objects.
38.j
If the maximum default Alignment is 8 (say,
Long_Float'Alignment = 8), then the implementation can refuse to accept
stricter alignments for subtypes. This simplifies the generated code,
since the compiler can align the stack and class-wide types to this maximum
without a substantial waste of space (or time).
38.k
Note that the recommended level of support takes
into account interactions between Size and Alignment. For example, on
a 32-bit machine with 8-bit storage elements, where load and store instructions
have to be aligned according to the size of the thing being loaded or
stored, the implementation might accept an Alignment of 1 if the Size
is 8, but might reject an Alignment of 1 if the Size is 32. On a machine
where unaligned loads and stores are merely inefficient (as opposed to
causing hardware traps), we would expect an Alignment of 1 to be supported
for any Size.
Wording Changes from Ada 83
38.l
The nonnegative part is missing from RM83 (for
mod_clauses,
nee
alignment_clauses, which are an obsolete
version of Alignment clauses).
Static Semantics
39/1
For a
prefix prefix
X that denotes an object:
40
X'Size
Denotes the size in bits of the
representation of the object. The value of this attribute is of the type
universal_integer.
40.a
Ramification: Note that Size is in bits
even if Machine_Radix is 10. Each decimal digit (and the sign) is presumably
represented as some number of bits.
41
Size
may be specified for [stand-alone] objects via an
attribute_definition_clause;
the expression of such a clause shall be static and its value nonnegative.
41.a/3
Aspect Description
for Size (object): Size
in bits of an object.
Implementation Advice
41.1/2
{
AI95-00051-02}
The size of an array object should not include
its bounds.
41.a.1/2
Implementation Advice:
The Size of an array object should not
include its bounds.
42/2
{
AI95-00051-02}
{
AI95-00291-02}
The recommended level
of support for the Size attribute of objects is
the same as for subtypes (see below), except that only a confirming Size
clause need be supported for an aliased elementary object.:
43/2
This paragraph
was deleted.{
AI95-00051-02}
A Size clause should be supported for an object
if the specified Size is at least as large as its subtype's Size, and
corresponds to a size in storage elements that is a multiple of the object's
Alignment (if the Alignment is nonzero).
Static Semantics
44
For every subtype S:
45
S'Size
If S is definite, denotes the
size [(in bits)] that the implementation would choose for the following
objects of subtype S:
46
A record component of subtype S when the
record type is packed.
47
The formal parameter of an instance of
Unchecked_Conversion that converts from subtype S to some other subtype.
48
If S is indefinite, the meaning is implementation
defined. The value of this attribute is of the type
universal_integer.
The Size of an object is at least
as large as that of its subtype, unless the object's Size is determined
by a Size clause, a component_clause, or a Component_Size clause. Size
may be specified for first subtypes via an
attribute_definition_clause;
the expression of such a clause shall be static and its value nonnegative.
48.a
Implementation defined: The meaning of
Size for indefinite subtypes.
48.b
Reason: The
effects of specifying the Size of a subtype are:
48.c
Unchecked_Conversion works in a predictable
manner.
48.d
A composite type cannot be packed so tightly
as to override the specified Size of a component's subtype.
48.e
Assuming the Implementation Advice is obeyed,
if the specified Size allows independent addressability, then the Size
of certain objects of the subtype should be equal to the subtype's Size.
This applies to stand-alone objects and to components (unless a
component_clause
or a Component_Size clause applies).
48.f/3
{
AI05-0229-1}
A
component_clause
or a Component_Size clause can cause an object to be smaller than its
subtype's specified size.
The aspect A
pragma
Pack cannot; if a component subtype's size is specified, this limits
how tightly the composite object can be packed.
48.g
The Size of a class-wide (tagged) subtype is
unspecified, because it's not clear what it should mean; it should certainly
not depend on all of the descendants that happen to exist in a given
program. Note that this cannot be detected at compile time, because in
a generic unit, it is not necessarily known whether a given subtype is
class-wide. It might raise an exception on some implementations.
48.h
Ramification:
A Size clause for a numeric subtype need not affect the underlying
numeric type. For example, if I say:
48.i
type S is range 1..2;
for S'Size use 64;
48.j
I am not guaranteed that S'Base'Last >= 2**63–1,
nor that intermediate results will be represented in 64 bits.
48.k
Reason: There is no need to complicate
implementations for this sort of thing, because the right way to affect
the base range of a type is to use the normal way of declaring the base
range:
48.l
type Big is range -2**63 .. 2**63 - 1;
subtype Small is Big range 1..1000;
48.m
Ramification: The Size of a large unconstrained
subtype (e.g. String'Size) is likely to raise Constraint_Error, since
it is a nonstatic expression of type universal_integer that might
overflow the largest signed integer type. There is no requirement that
the largest integer type be able to represent the size in bits of the
largest possible object.
48.n/3
Aspect Description
for Size (subtype): Size
in bits of a subtype.
Implementation Requirements
49
In an implementation, Boolean'Size shall be 1.
Implementation Advice
50/2
{
AI95-00051-02}
If the Size of a subtype
is specified, and allows
for efficient independent addressability (see
9.10)
on the target architecture, then the Size of the following objects of
the subtype should equal the Size of the subtype:
51
Aliased objects (including components).
52
Unaliased components, unless the Size of the component
is determined by a
component_clause
or Component_Size clause.
52.a.1/2
Implementation Advice:
If the Size of a subtype allows for
efficient independent addressability, then the Size of most objects of
the subtype should equal the Size of the subtype.
52.a
Ramification: Thus, on a typical 32-bit
machine, “for S'Size use 32;” will guarantee
that aliased objects of subtype S, and components whose subtype is S,
will have Size = 32 (assuming the implementation chooses to obey this
Implementation Advice). On the other hand, if one writes, “for
S2'Size use 5;” then stand-alone objects of subtype S2 will
typically have their Size rounded up to ensure independent addressability.
52.b
Note that “for S'Size use
32;” does not cause things like formal parameters to have Size
= 32 — the implementation is allowed to make all parameters be
at least 64 bits, for example.
52.c
Note that “for S2'Size use
5;” requires record components whose subtype is S2 to be exactly
5 bits if the record type is packed. The same is not true of array components;
their Size may be rounded up to the nearest factor of the word size.
52.d/2
Implementation Note: {
AI95-00291-02}
On most machines, arrays don't contain gaps between
elementary components; if the Component_Size
is greater than the Size of the component subtype, the extra bits are
generally considered part of each component, rather than gaps between
components. On the other hand, a record might contain gaps between
elementary
components, depending on what sorts of loads, stores, and masking
operations are generally done by the generated code.
52.e/2
{
AI95-00291-02}
For an array, any extra bits stored for each
elementary
component will generally be part of the component — the
whole point of storing extra bits is to make loads and stores more efficient
by avoiding the need to mask out extra bits. The PDP-10 is one counter-example;
since the hardware supports byte strings with a gap at the end of each
word, one would want to pack in that manner.
53
A Size clause on a composite subtype should not affect
the internal layout of components.
53.a.1/2
Implementation Advice:
A Size clause on a composite subtype
should not affect the internal layout of components.
53.a/3
54
The
recommended level of support for the Size attribute of subtypes is:
55
The Size (if not specified) of a static discrete
or fixed point subtype should be the number of bits needed to represent
each value belonging to the subtype using an unbiased representation,
leaving space for a sign bit only if the subtype contains negative values.
If such a subtype is a first subtype, then an implementation should support
a specified Size for it that reflects this representation.
55.a
Implementation Note: This applies to
static enumeration subtypes, using the internal codes used to represent
the values.
55.b
For a two's-complement machine, this implies
that for a static signed integer subtype S, if all values of S are in
the range 0 .. 2n–1,
or all values of S are in the range –2n–1
.. 2n–1–1,
for some n less than or equal to the word size, then S'Size should
be <= the smallest such n. For a one's-complement machine,
it is the same except that in the second range, the lower bound “–2n–1”
is replaced by “–2n–1+1”.
55.c
If an integer subtype (whether signed or unsigned)
contains no negative values, the Size should not include space for a
sign bit.
55.d
Typically, the implementation will choose to
make the Size of a subtype be exactly the smallest such n. However,
it might, for example, choose a biased representation, in which case
it could choose a smaller value.
55.e/3
{
AI05-0229-1}
On most machines, it is in general not a good idea to pack (parts of)
multiple stand-alone objects into the same storage element, because (1)
it usually doesn't save much space, and (2) it requires locking to prevent
tasks from interfering with each other, since separate stand-alone objects
are independently addressable. Therefore, if S'Size = 2 on a machine
with 8-bit storage elements, the size of a stand-alone object of subtype
S will probably not be 2. It might, for example, be 8, 16 or 32, depending
on the availability and efficiency of various machine instructions. The
same applies to components of composite types, unless
Pack packing,
Component_Size, or record layout is specified.
55.f
For an unconstrained discriminated object, if
the implementation allocates the maximum possible size, then the Size
attribute should return that maximum possible size.
55.g
Ramification: The Size of an object X
is not usually the same as that of its subtype S. If X is a stand-alone
object or a parameter, for example, most implementations will round X'Size
up to a storage element boundary, or more, so X'Size might be greater
than S'Size. On the other hand, X'Size cannot be less than S'Size, even
if the implementation can prove, for example, that the range of values
actually taken on by X during execution is smaller than the range of
S.
55.h
For example, if S is a first integer subtype
whose range is 0..3, S'Size will be probably be 2 bits, and components
of packed composite types of this subtype will be 2 bits (assuming Storage_Unit
is a multiple of 2), but stand-alone objects and parameters will probably
not have a size of 2 bits; they might be rounded up to 32 bits, for example.
On the other hand, Unchecked_Conversion will use the 2-bit size, even
when converting a stand-alone object, as one would expect.
55.i
Another reason for making the Size of an object
bigger than its subtype's Size is to support the run-time detection of
uninitialized variables.
The implementation might
add an extra value to a discrete subtype that represents the uninitialized
state, and check for this value on use. In some cases, the extra value
will require an extra bit in the representation of the object. Such detection
is not required by the language. If it is provided, the implementation
has to be able to turn it off. For example, if the programmer gives a
record_representation_clause
or Component_Size clause that makes a component too small to allow the
extra bit, then the implementation will not be able to perform the checking
(not using this method, anyway).
55.j
The fact that
the size of an object is not necessarily the same as its subtype can
be confusing:
55.k
type Device_Register is range 0..2**8 - 1;
for Device_Register'Size use 8; -- Confusing!
My_Device : Device_Register;
for My_Device'Address use To_Address(16#FF00#);
55.l
The programmer might think that My_Device'Size
is 8, and that My_Device'Address points at an 8-bit location. However,
this is not true. In Ada 83 (and in Ada 95), My_Device'Size might well
be 32, and My_Device'Address might well point at the high-order 8 bits
of the 32-bit object, which are always all zero bits. If My_Device'Address
is passed to an assembly language subprogram, based on the programmer's
assumption, the program will not work properly.
55.m
Reason: It is not reasonable to require
that an implementation allocate exactly 8 bits to all objects of subtype
Device_Register. For example, in many run-time models, stand-alone objects
and parameters are always aligned to a word boundary. Such run-time models
are generally based on hardware considerations that are beyond the control
of the implementer. (It is reasonable to require that an implementation
allocate exactly 8 bits to all components of subtype Device_Register,
if packed.)
55.n
Ramification:
The correct way to write the above code is like this:
55.o
type Device_Register is range 0..2**8 - 1;
My_Device : Device_Register;
for My_Device'Size use 8;
for My_Device'Address use To_Address(16#FF00#);
55.p
If the implementation cannot accept 8-bit stand-alone
objects, then this will be illegal. However, on a machine where an 8-bit
device register exists, the implementation will probably be able to accept
8-bit stand-alone objects. Therefore, My_Device'Size will be 8, and My_Device'Address
will point at those 8 bits, as desired.
55.q
If an object of subtype Device_Register is passed
to a foreign language subprogram, it will be passed according to that
subprogram's conventions. Most foreign language implementations have
similar run-time model restrictions. For example, when passing to a C
function, where the argument is of the C type char* (that is, pointer
to char), the C compiler will generally expect a full word value, either
on the stack, or in a register. It will not expect a single byte.
Thus, Size clauses for subtypes really have nothing to do with passing
parameters to foreign language subprograms.
56
For a subtype implemented with levels of indirection,
the Size should include the size of the pointers, but not the size of
what they point at.
56.a
Ramification: For example, if a task
object is represented as a pointer to some information (including a task
stack), then the size of the object should be the size of the pointer.
The Storage_Size, on the other hand, should include the size of the stack.
56.1/2
{
AI95-00051-02}
An implementation should support a Size clause
for a discrete type, fixed point type, record type, or array type, subject
to the following:
56.2/2
{
AI95-00051-02}
An implementation need not support a Size clause
for a signed integer type specifying a Size greater than that of the
largest signed integer type supported by the implementation in the absence
of a size clause (that is, when the size is chosen by default). A corresponding
limitation may be imposed for modular integer types, fixed point types,
enumeration types, record types, and array types.
56.b/2
Discussion: {
AI95-00051-02}
Note that the “corresponding limitation”
for a record or array type implies that an implementation may impose
some reasonable maximum size for records and arrays (e.g. 2**32 bits),
which is an upper bound (“capacity” limit) on the size, whether
chosen by default or by being specified by the user. The largest size
supported for records need not be the same as the largest size supported
for arrays.
56.b.1/3
Ramification: {
AI05-0155-1}
Only Size clauses with a size greater than or equal
to the Size that would be chosen by default may be safely presumed to
be supported on non-static elementary subtypes. Implementations may choose
to support smaller sizes, but only if the Size allows any value of the
subtype to be represented, for any possible value of the bounds.
56.3/2
{
AI95-00291-02}
A nonconfirming size clause for the first subtype
of a derived untagged by-reference type need not be supported.
56.c/2
Implementation Advice:
The recommended level of support for
the Size attribute should be followed.
56.d/2
Ramification: {
AI95-00291-02}
There is no recommendation to support any nonconfirming
Size clauses for types not mentioned above. Remember that 13.1
requires support for confirming Size clauses for all types.
57
7 Size is a subtype-specific attribute.
58/3
Inconsistencies With Ada 83
58.a.1/2
{
AI95-00114-01}
We specify the meaning of Size
in much more detail than Ada 83. This is not technically an inconsistency,
but it is in practice, as most Ada 83 compilers use a different definition
for Size than is required here. This should have been documented more
explicitly during the Ada 9X process.
Wording Changes from Ada 83
58.a
The requirement for a nonnegative value in a
Size clause was not in RM83, but it's hard to see how it would make sense.
For uniformity, we forbid negative sizes, rather than letting implementations
define their meaning.
Static Semantics
59/1
For a
prefix prefix
T that denotes a task object [(after any implicit dereference)]:
60/3
T'Storage_Size
{
AI05-0229-1}
Denotes the number of storage elements reserved for the task. The value
of this attribute is of the type
universal_integer. The Storage_Size
includes the size of the task's stack, if any. The language does not
specify whether or not it includes other storage associated with the
task (such as the “task control block” used by some implementations.)
If
the aspect a pragma
Storage_Size is
specified for the type of the object given,
the value of the Storage_Size attribute is at least the value
determined
by the aspect specified in the pragma.
60.a
Ramification: The value of this attribute
is never negative, since it is impossible to “reserve” a
negative number of storage elements.
60.b
If the implementation chooses to allocate an
initial amount of storage, and then increase this as needed, the Storage_Size
cannot include the additional amounts (assuming the allocation of the
additional amounts can raise Storage_Error); this is inherent in the
meaning of “reserved.”
60.c
The implementation is allowed to allocate different
amounts of storage for different tasks of the same subtype.
60.d
Storage_Size is also defined for access subtypes
— see
13.11.
61/3
{
AI95-0229-1}
[
Aspect
A pragma
Storage_Size specifies the amount of storage to be reserved for the execution
of a task.]
Syntax
62/3
63/3
64/3
Name Resolution Rules
65/3
Static Semantics
65.1/3
65.2/3
Storage_Size
The aspect Storage_Size is an expression,
which shall be of any integer type.
65.a/3
To be honest: This
definition somewhat conflicts with the "automatic" one for
the obsolescent attribute Storage_Size (which can be specified). The
only difference is where the given expression is evaluated. We intend
for the above definition to supersede that "automatic" definition
for this attribute.
65.b/3
Ramification: Note
that the value of the Storage_Size aspect is an expression;
it is not the value of an expression.
The expression
is evaluated for each object of the type (see below).
65.c/3
Aspect Description
for Storage_Size (task): Size
in storage elements reserved for a task type or single task object.
Legality Rules
65.3/3
{
AI05-0229-1}
The Storage_Size aspect shall not be specified
for a task interface type.
Dynamic Semantics
66/3
{
AI05-0229-1}
When a task object is created, the expression
(if any) associated with the Storage_Size aspect of its type A
pragma Storage_Size
is elaborated when an object of the type defined by the immediately enclosing
task_definition
is created. For the elaboration of a pragma
Storage_Size, the expression
is evaluated; the Storage_Size attribute of the newly created task object
is at least the value of the
expression.
66.a
Ramification: The implementation is allowed
to round up a specified Storage_Size amount. For example, if the implementation
always allocates in chunks of 4096 bytes, the number 200 might be rounded
up to 4096. Also, if the user specifies a negative number, the implementation
has to normalize this to 0, or perhaps to a positive number.
66.b/3
{
AI05-0229-1}
If the Storage_Size aspect is not specified for
the type of the task object, the value of the Storage_Size attribute
is unspecified.
67
At
the point of task object creation, or upon task activation, Storage_Error
is raised if there is insufficient free storage to accommodate the requested
Storage_Size.
Static Semantics
68/1
For a
prefix prefix
X that denotes an array subtype or array object [(after any implicit
dereference)]:
69
X'Component_Size
Denotes the size in bits of components
of the type of X. The value of this attribute is of type
universal_integer.
70
Component_Size
may be specified for array types via an
attribute_definition_clause;
the expression of such a clause shall be static, and its value nonnegative.
70.a
Implementation Note: The intent is that
the value of X'Component_Size is always nonnegative. If the array is
stored “backwards” in memory (which might be caused by an
implementation-defined pragma), X'Component_Size is still positive.
70.b
Ramification: For an array object A,
A'Component_Size = A(I)'Size for any index I.
70.c/3
Aspect Description
for Component_Size: Size
in bits of a component of an array type.
Implementation Advice
71
The
recommended level of support for the Component_Size attribute is:
72
An implementation need not support specified Component_Sizes
that are less than the Size of the component subtype.
73/3
{
AI05-0229-1}
An implementation should support specified Component_Sizes that are factors
and multiples of the word size. For such Component_Sizes, the array should
contain no gaps between components. For other Component_Sizes (if supported),
the array should contain no gaps between components when
Pack packing
is also specified; the implementation should forbid this combination
in cases where it cannot support a no-gaps representation.
73.a/3
Ramification: {
AI05-0229-1}
For example, if Storage_Unit = 8, and Word_Size = 32, then the user is
allowed to specify a Component_Size of 1, 2, 4, 8, 16, and 32, with no
gaps. In addition,
n*32 is allowed for positive integers
n,
again with no gaps. If the implementation accepts Component_Size = 3,
then it might allocate 10 components per word, with a 2-bit gap at the
end of each word (unless
Pack packing
is also specified), or it might not have any internal gaps at all. (There
can be gaps at either end of the array.)
73.b/2
Implementation Advice:
The recommended level of support for
the Component_Size attribute should be followed.
Static Semantics
73.1/3
73.2/3
X'Has_Same_Storage
{
AI05-0191-1}
X'Has_Same_Storage
denotes a function with the following specification:
73.3/3
function X'Has_Same_Storage (Arg : any_type)
return Boolean
73.4/3
{
AI05-0191-1}
{
AI05-0264-1}
The actual parameter shall be a name that denotes
an object. The object denoted by the actual parameter can be of any type.
This function evaluates the names of the objects involved and returns
True if the representation of the object denoted by the actual parameter
occupies exactly the same bits as the representation of the object denoted
by X; otherwise, it returns False.
73.c/3
Discussion: Has_Same_Storage
means that, if the representation is contiguous, the objects sit at the
same address and occupy the same length of memory.
73.5/3
73.6/3
X'Overlaps_Storage
{
AI05-0191-1}
X'Overlaps_Storage
denotes a function with the following specification:
73.7/3
function X'Overlaps_Storage (Arg : any_type)
return Boolean
73.8/3
{
AI05-0191-1}
{
AI05-0264-1}
The actual parameter shall be a name that denotes
an object. The object denoted by the actual parameter can be of any type.
This function evaluates the names of the objects involved and returns
True if the representation of the object denoted by the actual parameter
shares at least one bit with the representation of the object denoted
by X; otherwise, it returns False.
73.9/3
9 {
AI05-0191-1}
X'Has_Same_Storage(Y) implies X'Overlaps_Storage(Y).
73.10/3
10 {
AI05-0191-1}
X'Has_Same_Storage(Y) and X'Overlaps_Storage(Y)
are not considered to be reads of X and Y.
Static Semantics
73.11/3
74/1
{
8652/0009}
{
AI95-00137-01}
For every subtype S of a tagged type
T (specific or class-wide)
,
the following attribute is defined:
75/3
S'External_Tag
{
8652/0040}
{
AI95-00108-01}
{
AI05-0092-1}
S'External_Tag denotes an external
string representation for S'Tag; it is of the predefined type String.
External_Tag may be specified for a specific tagged type via an
attribute_definition_clause;
the expression of such a clause shall be static.
The default external tag representation is implementation defined. See
3.9.2 and 13.13.2.
The value of External_Tag is never inherited[;
the default value is always used unless a new value is directly specified
for a type].
75.a
Implementation defined: The default external
representation for a type tag.
75.b/3
Aspect Description
for External_Tag: Unique
identifier for a tagged type in streams.
Dynamic Semantics
75.1/3
{
AI05-0113-1}
If a user-specified external tag S'External_Tag
is the same as T'External_Tag for some other tagged type declared by
a different declaration in the partition, Program_Error is raised by
the elaboration of the attribute_definition_clause.
75.c/3
Ramification: This
rule does not depend on the visibility of the other tagged type, but
it does depend on the existence of the other tagged type. The other tagged
type could have the default external tag or a user-specified external
tag.
75.d/3
This rule allows the same
declaration to be elaborated multiple times. In that case, different
types could have the same external tag. If that happens, Internal_Tag
would return some unspecified tag, and Descendant_Tag probably would
return the intended tag (using the given ancestor to determine which
type is intended). However, in some cases (such as multiple instantiations
of a derived tagged type declared in a generic body), Tag_Error might
be raised by Descendant_Tag if multiple types are identified.
75.e/3
Note that while there
is a race condition inherent in this definition (which attribute_definition_clause
raises Program_Error depends on the order of elaboration), it doesn't
matter as a program with two such clauses is simply wrong. Two types
that both come from the same declaration are allowed, as noted previously.
Implementation Requirements
76
In an implementation, the default external tag for
each specific tagged type declared in a partition shall be distinct,
so long as the type is declared outside an instance of a generic body.
If the compilation unit in which a given tagged type is declared, and
all compilation units on which it semantically depends, are the same
in two different partitions, then the external tag for the type shall
be the same in the two partitions. What it means for a compilation unit
to be the same in two different partitions is implementation defined.
At a minimum, if the compilation unit is not recompiled between building
the two different partitions that include it, the compilation unit is
considered the same in the two partitions.
76.a
Implementation defined: What determines
whether a compilation unit is the same in two different partitions.
76.b
Reason: These requirements are important
because external tags are used for input/output of class-wide types.
These requirements ensure that what is written by one program can be
read back by some other program so long as they share the same declaration
for the type (and everything it depends on).
76.c
The user may specify the external tag if (s)he
wishes its value to be stable even across changes to the compilation
unit in which the type is declared (or changes in some unit on which
it depends).
76.d/2
{
AI95-00114-01}
We use a String rather than a
Stream_Element_Array Storage_Array
to represent an external tag for portability.
76.e
Ramification: Note that the characters
of an external tag need not all be graphic characters. In other words,
the external tag can be a sequence of arbitrary 8-bit bytes.
Implementation Permissions
76.1/3
{
AI05-0113-1}
If a user-specified external tag S'External_Tag
is the same as T'External_Tag for some other tagged type declared by
a different declaration in the partition, the partition may be rejected.
76.f/3
Ramification: This
is, in general, a post-compilation check. This permission is intended
for implementations that do link-time construction of the external tag
lookup table; implementations that dynamically construct the table will
likely prefer to raise Program_Error upon elaboration of the problem
construct. We don't want this check to require any implementation complexity,
as it will be very rare that there would be a problem.
77/2
11 {
AI95-00270-01}
The following language-defined attributes are specifiable, at least for
some of the kinds of entities to which they apply: Address,
Size,
Component_Size, Alignment,
Bit_Order, Component_Size,
External_Tag,
Input, Machine_Radix, Output,
Read, Size, Small,
Bit_Order, Storage_Pool,
Storage_Size,
Stream_Size, and Write
,
Output, Read, Input, and Machine_Radix.
78
12 It follows from the general rules in
13.1 that if one writes “
for
X'Size
use Y;” then the X'Size
attribute_reference
will return Y (assuming the implementation allows the Size clause). The
same is true for all of the specifiable attributes except Storage_Size.
78.a
Ramification: An implementation may specify
that an implementation-defined attribute is specifiable for certain entities.
This follows from the fact that the semantics of implementation-defined
attributes is implementation defined. An implementation is not allowed
to make a language-defined attribute specifiable if it isn't.
Examples
79
Examples of attribute
definition clauses:
80
Byte : constant := 8;
Page : constant := 2**12;
81
type Medium is range 0 .. 65_000;
for Medium'Size use 2*Byte;
for Medium'Alignment use 2;
Device_Register : Medium;
for Device_Register'Size use Medium'Size;
for Device_Register'Address use System.Storage_Elements.To_Address(16#FFFF_0020#);
82
type Short is delta 0.01 range -100.0 .. 100.0;
for Short'Size use 15;
83
for Car_Name'Storage_Size use -- specify access type's storage pool size
2000*((Car'Size/System.Storage_Unit) +1); -- approximately 2000 cars
84/2
{
AI95-00441-01}
function My_Input My_Read(Stream :
not null access Ada.Streams.Root_Stream_Type'Class)
return T;
for T'
Input Read use My_Input My_Read; --
see 13.13.2
85
13 Notes on the examples: In the
Size clause for Short, fifteen bits is the minimum necessary, since the
type definition requires Short'Small <= 2**(–7).
Extensions to Ada 83
85.a
The syntax rule for
length_clause
is replaced with the new syntax rule for
attribute_definition_clause,
and it is modified to allow a
name
(as well as an expression).
Wording Changes from Ada 83
85.b
85.c/2
{
AI95-00114-01}
In Ada 83, the relationship between a
aspect_clause representation_clause
specifying a certain aspect and an attribute that queried that aspect
was unclear. In Ada 95, they are the same, except for certain explicit
exceptions.
Wording Changes from Ada 95
85.d/2
{
8652/0009}
{
AI95-00137-01}
Corrigendum: Added wording to specify for
each attribute whether it is an operational or representation attribute.
85.e/2
85.f/2
{
AI95-00051-01}
{
AI95-00291-01}
Adjusted the Recommended Level of Support for Alignment
to eliminate nonsense requirements and to ensure that useful capabilities
are required.
85.g/2
{
AI95-00051-01}
{
AI95-00291-01}
Adjusted the Recommended Level of Support for Size
to eliminate nonsense requirements and to ensure that useful capabilities
are required. Also eliminated any dependence on whether an aspect was
specified (a confirming representation item should not affect the semantics).
85.h/2
85.i/2
{
AI95-00247-01}
Removed the requirement that specified alignments
for a composite type cannot override those for their components, because
it was never intended to apply to components whose location was specified
with a representation item. Moreover, it causes a difference in legality
when a confirming alignment is specified for one of the composite types.
85.j/2
{
AI95-00291-02}
Removed recommended level of support rules about
types with by-reference and aliased parts, because there are now blanket
rules covering all recommended level of support rules.
85.k/2
{
AI95-00291-02}
Split the definition of Alignment for subtypes
and for objects. This simplified the wording and eliminated confusion
about which rules applied to objects, which applied to subtypes, and
which applied to both.
Inconsistencies With Ada 2005
85.l/3
{
AI95-0095-1}
Correction: An address
attribute with a prefix of a generic formal subprogram whose actual parameter
has convention Intrinsic now raises Program_Error. Since it is unlikely
that such an attribute would have done anything useful (a subprogram
with convention Intrinsic is not expected to have a normal subprogram
body), it is highly unlikely that any existing programs would notice
the difference, and any that do probably are buggy.
85.m/3
{
AI95-0113-1}
Correction: User-specified external tags
that conflict with other external tags raise Program_Error (or are optionally
illegal). This was legal and did not raise an exception in the past,
although the effects were not defined. So while a program might depend
on such behavior, the results were not portable (even to different versions
of the same implementation). Such programs should be rare.
Incompatibilities With Ada 2005
85.n/3
{
AI05-0095-1}
Correction: An address
attribute with a prefix of a subprogram with convention Intrinsic is
now illegal. Such attributes are very unlikely to have provided a useful
answer (the intended meaning of convention Intrinsic is that there is
no actual subprogram body for the operation), so this is highly unlikely
to affect any existing programs unless they have a hidden bug.
Extensions to Ada 2005
85.o/3
{
AI05-0191-1}
Attributes Has_Same_Storage
and Overlaps_Storage are new.
85.p/3
{
AI05-0229-1}
Aspect Storage_Size is new; pragma
Storage_Size is now obsolescent, joining attribute Storage_Size for task
types.
Wording Changes from Ada 2005
85.q/3
{
AI05-0009-1}
Correction: Improved the description of
erroneous execution for address clauses to make it clear that specifying
an address inappropriate for the entity will lead to erroneous execution.
85.r/3
{
AI05-0116-1}
Correction: Added Implementation Advice
for the alignment of class-wide types.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe