13.1 Operational and Representation ItemsRepresentation Items
0.1/3
{
8652/0009}
{
AI95-00137-01}
{
AI05-0183-1}
[Representation and operational items can be used
to specify aspects of entities. Two kinds of aspects of entities can
be specified: aspects of representation and operational aspects. Representation
items specify how the types and other entities of the language are to
be mapped onto the underlying machine. Operational items specify other
properties of entities. In addition to representation
and operational items, aspects of entities may be specified using an
aspect_specification
(see 13.3.1), which is an optional element
of certain kinds of declarations. ]
1/1
{
8652/0009}
{
AI95-00137-01}
There are
six three kinds
of
representation items:
attribute_definition_clauses
for representation attributes, enumeration_representation_clauses,
record_representation_clauses,
at_clauses,
representation_clauses,
component_clauses,
and
representation pragmas. [
Representation
items specify how the types and other entities of the language are to
be mapped onto the underlying machine. They can be provided to
give more efficient representation or to interface with features that
are outside the domain of the language (for example, peripheral hardware).
Representation items also specify other specifiable
properties of entities. A representation item applies to an entity identified
by a local_name,
which denotes an entity declared local to the current declarative region,
or a library unit declared immediately preceding a representation pragma
in a compilation.]
1.1/1
1.2/1
{
8652/0009}
{
AI95-00137-01}
[An operational item or a representation item applies
to an entity identified by a local_name,
which denotes an entity declared local to the current declarative region,
or a library unit declared immediately preceding a representation pragma
in a compilation.]
Language Design Principles
1.a.1/1
{
8652/0009}
{
AI95-00137-01}
Aspects of representation are intended to refer
to properties that need to be known before the compiler can generate
code to create or access an entity. For instance, the size of an object
needs to be known before the object can be created. Conversely, operational
aspects are those that only need to be known before they can be used.
For instance, how an object is read from a stream only needs to be known
when a stream read is executed. Thus, aspects of representation have
stricter rules as to when they can be specified.
1.a.2/2
{
AI95-00291-02}
Confirming the value of an aspect with an operational
or representation item should never change the semantics of the aspect.
Thus Size = 8 (for example) means the same thing whether it was specified
with a representation item or whether the compiler chose this value by
default.
Syntax
2/1
3
4/1
Name Resolution Rules
5/1
{
8652/0009}
{
AI95-00137-01}
In
an operational item or a
representation item, if the
local_name
is a
direct_name,
then it shall resolve to denote a declaration (or, in the case of a
pragma,
one or more declarations) that occurs immediately within the same declarative
region as the
representation item. If the
local_name
has an
attribute_designator,
then it shall resolve to denote an implementation-defined component (see
13.5.1) or a class-wide type implicitly
declared immediately within the same declarative region as the
representation
item. A
local_name
that is a
library_unit_name
(only permitted in a representation pragma) shall resolve to denote the
library_item
that immediately precedes (except for other pragmas) the representation
pragma.
5.a/1
Reason: {
8652/0009}
{
AI95-00137-01}
This is a Name Resolution Rule, because we don't want
an
operational or a representation item
for X to be ambiguous just because there's another X declared in an outer
declarative region. It doesn't make much difference, since most
operational
or representation items are for types or subtypes, and type and
subtype names can't be overloaded.
5.b/1
Ramification: {
8652/0009}
{
AI95-00137-01}
The visibility rules imply that the declaration has to occur before the
operational or representation item.
5.c/1
{
8652/0009}
{
AI95-00137-01}
For objects, this implies that
operational or representation
items can be applied only to stand-alone objects.
Legality Rules
6/1
6.a
Ramification: The “statically denote”
part implies that it is impossible to specify the representation of an
object that is not a stand-alone object, except in the case of a representation
item like pragma Atomic that is allowed inside a
component_list
(in which case the representation item specifies the representation of
components of all objects of the type). It also prevents the problem
of renamings of things like “P.
all” (where P is an
access-to-subprogram value) or “E(I)” (where E is an entry
family).
6.b
The part about where the denoted entity has
to have been declared appears twice — once as a Name Resolution
Rule, and once as a Legality Rule. Suppose P renames Q, and we have a
representation item in a
declarative_part
whose
local_name
is P. The fact that the representation item has to appear in the same
declarative_part
as P is a Name Resolution Rule, whereas the fact that the representation
item has to appear in the same
declarative_part
as Q is a Legality Rule. This is subtle, but it seems like the least
confusing set of rules.
6.c
7/2
{
AI95-00291-02}
The
representation of
an object consists of a certain number of bits (the
size of the
object).
For an object of an elementary type, these These
are the bits that are normally read or updated by the machine code when
loading, storing, or operating-on the value of the object.
For
an object of a composite type, these are the bits reserved for this object,
and include bits occupied by subcomponents of the object. If This
includes some padding bits, when the size of
an the
object is greater than
that the
size of its subtype
, the additional bits
are padding bits.. For
an elementary object, these Such
padding bits
are considered to be part of the representation
of the object, rather than being gaps between objects, if these bits
are normally read and updated
along with
the others. For a composite object, padding bits might not be read or
updated in any given composite operation, depending on the implementation.
7.a/2
To be honest: {
AI95-00291-02}
Discontiguous representations
are allowed, but the ones we're interested in here are generally contiguous
sequences of bits.
For a discontiguous representation,
the size doesn't necessarily describe the “footprint” of
the object in memory (that is, the amount of space taken in the address
space for the object).
7.a.1/2
Discussion: {
AI95-00291-02}
In the case of composite objects, we want the implementation
to have the flexibility to either do operations component-by-component,
or with a block operation covering all of the bits. We carefully avoid
giving a preference in the wording. There is no requirement for the choice
to be documented, either, as the implementation can make that choice
based on many factors, and could make a different choice for different
operations on the same object.
7.a.2/2
{
AI95-00291-02}
In the case of a properly aligned, contiguous object
whose size is a multiple of the storage unit size, no other bits should
be read or updated as part of operating on the object. We don't say this
normatively because it would be difficult to normatively define “properly
aligned” or “contiguous”.
7.b
Ramification:
Two objects with the same value do not necessarily have the same
representation. For example, an implementation might represent False
as zero and True as any odd value. Similarly, two objects (of the same
type) with the same sequence of bits do not necessarily have the same
value. For example, an implementation might use a biased representation
in some cases but not others:
7.c/3
{
AI05-0229-1}
subtype S
is Integer
range 1..256;
type A
is array(Natural
range 1..4)
of S
with Pack;
pragma Pack(A);
X : S := 3;
Y : A := (1, 2, 3, 4);
7.d
The implementation might use a biased-by-1 representation
for the array elements, but not for X. X and Y(3) have the same value,
but different representation: the representation of X is a sequence of
(say) 32 bits: 0...011, whereas the representation of Y(3) is a sequence
of 8 bits: 00000010 (assuming a two's complement representation).
7.e
Such tricks are not required, but are allowed.
7.f
Discussion: The value of any padding
bits is not specified by the language, though for a numeric type, it
will be much harder to properly implement the predefined operations if
the padding bits are not either all zero, or a sign extension.
7.g/3
Ramification: {
AI05-0229-1}
For example, suppose S'Size = 2, and an object X is of subtype S. If
the machine code typically uses a 32-bit load instruction to load the
value of X, then X'Size should be 32, even though 30 bits of the value
are just zeros or sign-extension bits. On the other hand, if the machine
code typically masks out those 30 bits, then X'Size should be 2. Usually,
such masking only happens for components of a composite type for which
Pack packing,
Component_Size, or record layout is specified.
7.h
Note, however, that the formal parameter of
an instance of Unchecked_Conversion is a special case. Its Size is required
to be the same as that of its subtype.
7.i
Note that we don't generally talk about the
representation of a value. A value is considered to be an amorphous blob
without any particular representation. An object is considered to be
more concrete.
8/3
{
AI05-0112-1}
A representation
item
directly specifies an
aspect of representation of
the entity denoted by the
local_name,
except in the case of a type-related representation item, whose
local_name
shall denote a first subtype, and which directly specifies an aspect
of the subtype's type.
A
representation item that names a subtype is either
subtype-specific
(Size and Alignment clauses) or
type-related (all others). [Subtype-specific
aspects may differ for different subtypes of the same type.]
Unless otherwise specified, the name of the aspect of representation
specified by a representation pragma is the name of the pragma.
8.a
To be honest: Type-related and
subtype-specific are defined likewise for the corresponding aspects
of representation.
8.b
To be honest: Some representation items
directly specify more than one aspect.
8.c/3
Discussion: {
AI05-0229-1}
For example, a
pragma
Export
(see J.15.5)
specifies the convention of an entity, and also specifies that
it is exported.
Such items are obsolescent; directly
specifying the associated aspects is preferred.
8.d
8.e
8.e.1/3
{
AI05-0112-1}
We give a default naming for representation aspects
of representation pragmas so we don't have to do that for every pragma.
Operational and representation attributes are given a default naming
in 13.3. We don't want any anonymous aspects;
that would make other rules more difficult to write and understand.
8.f
Ramification:
The following representation items are type-related:
8.g
8.h
8.i
Component_Size clause
8.j/1
8.k
Small clause
8.l
Bit_Order clause
8.m
Storage_Pool clause
8.n
Storage_Size clause
8.n.1/2
8.o/1
8.p/1
8.q/1
8.r/1
8.s
Machine_Radix clause
8.t
pragma Pack
8.u
pragmas Import, Export, and Convention (when
applied to a type)
8.v/3
{
AI05-0009-1}
pragmas Atomic
, Independent, and Volatile
(when applied to a type)
8.w/3
{
AI05-0009-1}
pragmas Atomic_Components
, Independent_Components,
and Volatile_Components (when applied to
a an
array type)
8.x
pragma Discard_Names (when applied to an enumeration
or tagged type)
8.y
The following
representation items are subtype-specific:
8.z
Alignment clause (when applied to a first
subtype)
8.aa
Size clause (when applied to a first subtype)
8.bb
The following
representation items do not apply to subtypes, so they are neither type-related
nor subtype-specific:
8.cc
Address clause (applies to objects and program
units)
8.dd
Alignment clause (when applied to an object)
8.ee
Size clause (when applied to an object)
8.ff
pragmas Import, Export, and Convention (when
applied to anything other than a type)
8.gg
pragmas Atomic and Volatile (when applied
to an object or a component)
8.hh/3
{
AI05-0009-1}
pragmas Atomic_Components
, Independent_Components,
and Volatile_Components (when applied to an array object)
8.ii
pragma Discard_Names (when applied to an exception)
8.jj
pragma Asynchronous (applies to procedures)
8.kk/2
8.ll/3
{
AI05-0229-1}
While an aspect_specification
is not a representation item, a similar categorization applies to the
aspect that corresponds to each of these representation items (along
with aspects that do not have associated representation items).
8.1/3
{
8652/0009}
{
AI95-00137-01}
{
AI05-0183-1}
An operational item directly specifies an
operational aspect of the entity type
of the subtype denoted by the local_name,
except in the case of a type-related operational item, whose local_name
shall denote a first subtype, and which directly specifies an aspect
of the type of the subtype.
The local_name
of an operational item shall denote a first subtype. An operational item
that names a subtype is type-related.
8.mm/1
8.nn/1
External_Tag clause
8.oo/1
Read clause
8.pp/1
Write clause
8.qq/1
Input clause
8.rr/1
Output clause
9/3
{
AI05-0183-1}
A representation item that directly specifies an aspect of a subtype
or type shall appear after the type is completely defined (see
3.11.1),
and before the subtype or type is frozen (see
13.14).
If a representation item
or aspect_specification
is given that directly specifies an aspect of an entity, then
it is illegal to give another representation item
or
aspect_specification
that directly specifies the same aspect of the entity.
9.a/1
Ramification: {
8652/0009}
{
AI95-00137-01}
The fact that a representation item
(or operational
item, see next paragraph) that directly specifies an aspect of
an entity is required to appear before the entity is frozen prevents
changing the representation of an entity after using the entity in ways
that require the representation to be known.
9.b/3
To be honest: {
AI05-0183-1}
The rule preventing multiple specification is also
intended to cover other ways to specify representation aspects, such
as obsolescent pragma
Priority. Priority is not a representation pragma, and as such is neither
a representation item nor an aspect_specification.
Regardless, giving both a pragma
Priority and an aspect_specification
for Priority is illegal. We didn't want to complicate the wording solely
to support obsolescent features.
9.1/3
{
8652/0009}
{
AI95-00137-01}
{
AI05-0183-1}
An operational item that directly specifies an
aspect of an entity a
type shall appear before the entity type is frozen (see 13.14). If an operational
item or aspect_specification
is given that directly specifies an aspect
of an entity a
type, then it is illegal to give
another operational item or aspect_specification
that directly specifies the same aspect
of the entity type.
9.c/1
Ramification: Unlike
representation items, operational items can be specified on partial views.
Since they don't affect the representation, the full declaration need
not be known to determine their legality.
9.2/3
{
AI05-0106-1}
Unless otherwise specified, an operational or representation
item shall not specify an aspect of a generic formal parameter.
9.d/3
Reason: Specifying
an aspect on a generic formal parameter implies an added contract for
a generic unit. That contract needs to be defined via generic parameter
matching rules, and, as aspects vary widely, that has to be done for
each such aspect. Since most aspects do not need this complexity (including
all language-defined aspects as of this writing), we avoid the complexity
by saying that such contract-forming aspect specifications are banned
unless the rules defining them explicitly exist.
10
For an untagged derived type, no type-related representation
items are allowed if the parent type is a by-reference type, or has any
user-defined primitive subprograms.
10.a/1
Ramification: {
8652/0009}
{
AI95-00137-01}
On the other hand, subtype-specific representation items may be given
for the first subtype of such a type
, as can operational
items.
10.b/3
Reason: {
AI05-0229-1}
The reason for forbidding type-related representation items on untagged
by-reference types is because a change of representation is impossible
when passing by reference (to an inherited subprogram). The reason for
forbidding type-related representation items on untagged types with user-defined
primitive subprograms was to prevent implicit change of representation
for type-related aspects of representation upon calling inherited subprograms,
because such changes of representation are likely to be expensive at
run time. Changes of subtype-specific representation attributes, however,
are likely to be cheap. This rule is not needed for tagged types, because
other rules prevent a type-related representation item from changing
the representation of the parent part; we want to allow a type-related
representation item on a type extension to specify aspects of the extension
part. For example,
specifying aspect a
pragma
Pack will cause packing of the extension part, but not of the parent
part.
11/2
{
8652/0009}
{
AI95-00137-01}
{
8652/0011} {
AI95-00117-01}
{
AI95-00326-01}
Operational and representation Representation
aspects of a generic formal parameter are the same as those of the actual.
Operational and representation aspects of
a partial view are the same for
all views of a type as
those of the full view. A
type-related representation item is not allowed for a descendant of a
generic formal untagged type.
11.a/1
Ramification: {
8652/0009}
{
AI95-00137-01}
Representation items are allowed for types whose subcomponent types or
index subtypes are generic formal types.
Operational
items and subtype-related representation items are allowed on descendants
of generic formal types.
11.b
Reason: Since it is not known whether
a formal type has user-defined primitive subprograms, specifying type-related
representation items for them is not allowed, unless they are tagged
(in which case only the extension part is affected in any case).
11.c/2
Ramification: {
AI95-00326-01}
All views of a type, including the incomplete and
partial views, have the same operational and representation aspects.
That's important so that the properties don't change when changing views.
While most aspects are not available for an incomplete view, we don't
want to leave any holes by not saying that they are the same.
11.d/3
{
AI05-0083-1}
However, this does not apply to objects. Different
views of an object can have different representation aspects. For instance,
an actual object passed by reference and the associated formal parameter
may have different values for Alignment even though the formal parameter
is merely a view of the actual object. This is necessary to maintain
the language design principle that Alignments are always known at compile
time.
12
A representation item that specifies the Size for
a given subtype, or the size or storage place for an object (including
a component) of a given subtype, shall allow for enough storage space
to accommodate any value of the subtype.
13/1
{
8652/0009}
{
AI95-00137-01}
A representation
or operational item that
is not supported by the implementation is illegal, or raises an exception
at run time.
13.1/2
{
AI95-00251-01}
A type_declaration
is illegal if it has one or more progenitors, and a representation item
applies to an ancestor, and this representation item conflicts with the
representation of some other ancestor. The cases that cause conflicts
are implementation defined.
13.a/2
Implementation defined:
The cases that cause conflicts between
the representation of the ancestors of a type_declaration.
13.b/2
Reason:
This rule is needed because it may be the case that only the combination
of types in a type declaration causes a conflict. Thus it is not possible,
in general, to reject the original representation item. For instance:
13.c/2
package Pkg1 is
type Ifc is interface;
type T is tagged record
Fld : Integer;
end record;
for T use record
Fld at 0 range 0 .. Integer'Size - 1;
end record;
end Pkg1;
13.d/2
Assume
the implementation uses a single tag with a default offset of zero, and
that it allows the use of non-default locations for the tag (and thus
accepts representation items like the one above). The representation
item will force a non-default location for the tag (by putting a component
other than the tag into the default location). Clearly, this package
will be accepted by the implementation. However, other declarations could
cause trouble. For instance, the implementation could reject:
13.e/2
with Pkg1;
package Pkg2 is
type NewT is new Pkg1.T and Pkg1.Ifc with null record;
end Pkg2;
13.f/2
because the declarations
of T and Ifc have a conflict in their representation items. This is clearly
necessary (it's hard to imagine how Ifc'Class could work with the tag
at a location other than the one it is expecting).
13.g/2
Conflicts will usually
involve implementation-defined attributes (for specifying the location
of the tag, for instance), although the example above shows that doesn't
have to be the case. For this reason, we didn't try to specify exactly
what causes a conflict; it will depend on the implementation's implementation
model and what representation items it allows.
13.h/2
Implementation Note:
An implementation can only use this rule to reject type_declarations
where one of its ancestors has a representation item. An implementation
must ensure that the default representations of ancestors cannot conflict.
Static Semantics
14
If two subtypes statically match, then their subtype-specific
aspects (Size and Alignment) are the same.
14.a
Reason: This is necessary because we
allow (for example) conversion between access types whose designated
subtypes statically match. Note that it is illegal to specify an aspect
(including a subtype-specific one) for a nonfirst subtype.
14.b
Consider, for
example:
14.c/1
package P1 is
subtype S1 is Integer range 0..2**16-1;
for S1'Size use 16; -- Illegal!
-- S1'Size would be 16 by default.
type A1 is access all S1;
X1: A1;
end P1;
14.d/1
package P2 is
subtype S2 is Integer range 0..2**16-1;
for S2'Size use 32; -- Illegal!
type A2 is access all S2;
X2: A2;
end P2;
14.e/3
{
AI05-0229-1}
procedure Q
is
use P1, P2;
type Array1
is array(Integer
range <>)
of aliased S1
with Pack;
pragma Pack(Array1);
Obj1: Array1(1..100);
type Array2
is array(Integer
range <>)
of aliased S2
with Pack;
pragma Pack(Array2);
Obj2: Array2(1..100);
begin
X1 := Obj2(17)'
Unchecked_ Access;
X2 := Obj1(17)'
Unchecked_ Access;
end Q;
14.f
Loads and stores through X1 would read and write
16 bits, but X1 points to a 32-bit location. Depending on the endianness
of the machine, loads might load the wrong 16 bits. Stores would fail
to zero the other half in any case.
14.g
Loads and stores through X2 would read and write
32 bits, but X2 points to a 16-bit location. Thus, adjacent memory locations
would be trashed.
14.h
Hence, the above is illegal. Furthermore, the
compiler is forbidden from choosing different Sizes by default, for the
same reason.
14.i
The same issues apply to Alignment.
15/3
{
8652/0040}
{
AI95-00108-01}
{
AI05-0009-1}
A derived type inherits each type-related aspect
of
representation of its parent type that was directly specified
before the declaration of the derived type, or (in the case where the
parent is derived) that was inherited by the parent type from the grandparent
type. A derived subtype inherits each subtype-specific aspect
of
representation of its parent subtype that was directly specified
before the declaration of the derived type, or (in the case where the
parent is derived) that was inherited by the parent subtype from the
grandparent subtype, but only if the parent subtype statically matches
the first subtype of the parent type. An inherited aspect of representation
is overridden by a subsequent representation item that specifies
a
different value for the same aspect of the type or subtype.
15.a
To be honest: A
record_representation_clause
for a record extension does not override the layout of the parent part;
if the layout was specified for the parent type, it is inherited by the
record extension.
15.b
Ramification: If a representation item
for the parent appears after the
derived_type_definition,
then inheritance does not happen for that representation item.
15.b.1/3
{
AI05-0009-1}
If an inherited aspect is confirmed by a later
representation item for a derived type, the confirming representation
item does not override the inherited one. Thus the derived type has both
a specified confirming and an inherited non-confirming representation
item — this means that rules that apply only to non-confirming
representation items still apply to this type.
15.1/3
{
8652/0040}
{
AI95-00108-01}
{
AI95-00444-01}
{
AI05-0183-1}
In contrast, whether operational aspects are inherited
by a an
untagged a derived type depends on each specific aspect;
unless specified, an operational aspect is not inherited.
[Operational
aspects are never inherited for a tagged type.] When
operational aspects are inherited by a an
untagged a derived type, aspects that were directly specified by
operational items that are visible at the point before
the declaration of the derived type declaration, or (in the case where the parent
is derived) that were inherited by the parent type from the grandparent
type are inherited. An inherited operational aspect is overridden by
a subsequent operational item that specifies the same aspect of the type.
15.b.2/1
Ramification: As
with representation items, if an operational item for the parent appears
after the derived_type_definition,
then inheritance does not happen for that operational item.
15.b.3/3
Discussion: {
AI95-00444-01}
{
AI05-0183-1}
Only Currently,
only untagged
types inherit operational aspects. Inheritance
from tagged types causes problems, as the different views can have different
visibility on operational items — potentially leading to operational
items that depend on the view. We want aspects to be the same for all
views. Untagged types don't have this problem as plain private types
don't have ancestors, and thus can't inherit anything. In addition, it
seems unlikely that we'll need inheritance for tagged types, as usually
we'll want to incorporate the parent's operation into a new one that
also handles any extension components. We
considered writing this rule that way, but rejected it as that could
be too specific for future operational aspects. (After all, that is precisely
the problem that caused us to introduce “operational aspects”
in the first place.)
15.2/2
{
AI95-00444-01}
When an aspect that is a subprogram is inherited,
the derived type inherits the aspect in the same way that a derived type
inherits a user-defined primitive subprogram from its parent (see 3.4).
15.c/2
Reason: This defines
the parameter names and types, and the needed implicit conversions.
16
Each aspect of representation
of an entity is as follows:
17
If the aspect is
specified
for the entity, meaning that it is either directly specified or inherited,
then that aspect of the entity is as specified, except in the case of
Storage_Size, which specifies a minimum.
17.a
Ramification: This rule implies that
queries of the aspect return the specified value. For example, if the
user writes “for X'Size use 32;”, then a query
of X'Size will return 32.
18
If an aspect of representation
of an entity is not specified, it is chosen by default in an unspecified
manner.
18.a/1
18.b
The rules forbid things like “for
S'Base'Alignment use ...” and “for S'Base use
record ...”.
18.c
Discussion: The intent is that implementations
will represent the components of a composite value in the same way for
all subtypes of a given composite type. Hence, Component_Size and record
layout are type-related aspects.
18.d/3
Ramification: {
AI05-0083-1}
As noted previously, in the case of an object,
the entity mentioned in this text is a specific view of an object. That
means that only references to the same view of an object that has a specified
value for a representation aspect R necessarily have that value
for the aspect R. The value of the aspect R for a different
view of that object is unspecified. In particular, this means that the
representation values for by-reference parameters is unspecified; they
do not have to be the same as those of the underlying object.
18.1/1
{
8652/0040}
{
AI95-00108-01}
If an operational aspect is
specified for an entity (meaning that it is either directly specified
or inherited), then that aspect of the entity is as specified. Otherwise,
the aspect of the entity has the default value for that aspect.
18.2/2
{
AI95-00291-02}
A representation item that specifies an aspect
of representation that would have been chosen in the absence of the representation
item is said to be confirming.
Dynamic Semantics
19/1
19.a
Ramification: Elaboration of representation
pragmas is covered by the general rules for pragmas in Section 2.
Implementation Permissions
20
An implementation may interpret aspects of representation
in an implementation-defined manner. An implementation may place implementation-defined
restrictions on representation items.
A
recommended
level of support is specified for representation items and related
features in each subclause. These recommendations are changed to requirements
for implementations that support the Systems Programming Annex (see
C.2,
“
Required Representation Support”).
20.a
Implementation defined: The interpretation
of each aspect of representation.
20.b
Implementation defined: Any restrictions
placed upon representation items.
20.c
Ramification: Implementation-defined
restrictions may be enforced either at compile time or at run time. There
is no requirement that an implementation justify any such restrictions.
They can be based on avoiding implementation complexity, or on avoiding
excessive inefficiency, for example.
20.c.1/1
Implementation Advice
21
The
recommended level of support for all representation items is qualified
as follows:
21.1/2
{
AI95-00291-02}
A confirming representation item should be supported.
21.a.1/2
To be honest: A
confirming representation item might not be possible for some entities.
For instance, consider an unconstrained array. The size of such a type
is implementation-defined, and might not actually be a representable
value, or might not be static.
22
An implementation need not support representation
items containing nonstatic expressions, except that an implementation
should support a representation item for a given entity if each nonstatic
expression in the representation item is a name that statically denotes
a constant declared before the entity.
22.a
Reason: This
is to avoid the following sort of thing:
22.b
X : Integer := F(...);
Y : Address := G(...);
for X'Address use Y;
22.c
In the above, we have to evaluate the initialization
expression for X before we know where to put the result. This seems like
an unreasonable implementation burden.
22.d
The above code
should instead be written like this:
22.e
Y : constant Address := G(...);
X : Integer := F(...);
for X'Address use Y;
22.f
This allows the expression “Y” to
be safely evaluated before X is created.
22.g
The constant could be a formal parameter of
mode in.
22.h
An implementation can support other nonstatic
expressions if it wants to. Expressions of type Address are hardly ever
static, but their value might be known at compile time anyway in many
cases.
23
An implementation need not support a specification
for the Size for a given composite subtype, nor the size or storage place
for an object (including a component) of a given composite subtype, unless
the constraints on the subtype and its composite subcomponents (if any)
are all static constraints.
24/2
{
AI95-00291-02}
An implementation need not support a nonconfirming
representation item if it could cause an aliased object or an object
of a by-reference type to be allocated at a nonaddressable location or,
when the alignment attribute of the subtype of such an object is nonzero,
at an address that is not an integral multiple of that alignment. An
aliased component, or a component whose type is by-reference, should
always be allocated at an addressable location.
24.a/1
Reason: The intent is that access types,
type System.Address, and the pointer used for a by-reference parameter
should be implementable as a single machine address — bit-field
pointers should not be required. (There is no requirement that this implementation
be used — we just want to make sure it's its
feasible.)
24.b/2
Implementation Note: {
AI95-00291-02}
We want subprograms to be able to assume the properties
of the types of their parameters inside of subprograms. While many objects
can be copied to allow this (and thus do not need limitations), aliased
or by-reference objects cannot be copied (their memory location is part
of their identity). Thus, Note that
the above rule does not apply to types that merely allow by-reference
parameter passing; for such types, a copy typically needs to be made
at the call site when a bit-aligned component is passed as a parameter.
25/2
{
AI95-00291-02}
An implementation need not support a nonconfirming
representation item if it could cause an aliased object of an elementary
type to have a size other than that which would have been chosen by default.
25.a/2
Reason: Since all
bits of elementary objects participate in operations, aliased objects
must not have a different size than that assumed by users of the access
type.
26/2
{
AI95-00291-02}
An implementation need not support a nonconfirming
representation item if it could cause an aliased object of a composite
type, or an object whose type is by-reference, to have a size smaller
than that which would have been chosen by default.
26.a/2
Reason: Unlike
elementary objects, there is no requirement that all bits of a composite
object participate in operations. Thus, as long as the object is the
same or larger in size than that expected by the access type, all is
well.
26.b/2
Ramification: This
rule presumes that the implementation allocates an object of a size specified
to be larger than the default size in such a way that access of the default
size suffices to correctly read and write the value of the object.
27/2
{
AI95-00291-02}
An implementation need not support a nonconfirming
subtype-specific representation item specifying an aspect of representation
of an indefinite or abstract subtype.
27.a/2
Reason: Aspects
of representations are often not well-defined for such types.
27.b/2
28/2
{
AI95-00291-02}
For purposes of these rules, the determination
of whether a representation item applied to a type could cause
an object to have some property is based solely on the properties of
the type itself, not on any available information about how the type
is used. In particular, it presumes that minimally aligned objects of
this type might be declared at some point.
28.a/2
Implementation Advice:
The recommended level of support for
all representation items should be followed.
29/3
1 {
AI05-0229-1}
Aspects that can be specified are defined throughout
this International Standard, and are summarized in K.1.
Incompatibilities With Ada 83
29.a
It is now illegal for a
representation item to cause a derived by-reference type to have a different
record layout from its parent. This is necessary for by-reference parameter
passing to be feasible. This only affects programs that specify the representation
of types derived from types containing tasks; most by-reference types
are new to Ada 95. For example, if A1 is an array of tasks, and A2 is
derived from A1, it is illegal to apply a
pragma
Pack to A2.
Extensions to Ada 83
29.b/1
Wording Changes from Ada 83
29.c/1
{
8652/0009}
{
AI95-00137-01}
The syntax rule for
type_representation_clause
is removed; the right-hand side of that rule is moved up to where it
was used, in
aspect_clause representation_clause.
There are two references to “type representation clause”
in RM83, both in Section 13; these have been reworded.
Also,
the representation_clause has been renamed
the aspect_clause
to reflect that it can be used to control more than just representation
aspects.
29.d/2
{
8652/0009}
{
AI95-00137-01}
{
AI95-00114-01}
We have defined a new term “representation item,” which includes
all representation clauses representation_clauses
and representation pragmas, as well as
component_clauses.
This is convenient because the rules are almost identical for all
of
them three.
We
have also defined the new terms “operational item” and “operational
aspects” in order to conveniently handle new types of specifiable specifable entities.
29.e
All of the forcing occurrence stuff has been
moved into its own subclause (see
13.14),
and rewritten to use the term “freezing”.
29.f
RM83-13.1(10) requires implementation-defined
restrictions on representation items to be enforced at compile time.
However, that is impossible in some cases. If the user specifies a junk
(nonstatic) address in an address clause, and the implementation chooses
to detect the error (for example, using hardware memory management with
protected pages), then it's clearly going to be a run-time error. It
seems silly to call that “semantics” rather than “a
restriction.”
29.g
RM83-13.1(10) tries to pretend that representation_clauses
don't affect the semantics of the program. One counter-example is the
Small clause. Ada 95 has more counter-examples. We have noted the opposite
above.
29.h
Extensions to Ada 95
29.i/2
{
AI95-00291-02}
Amendment Correction:
Confirming representation items are defined, and the recommended level
of support is now that they always be supported.
Wording Changes from Ada 95
29.j/2
{
8652/0009}
{
AI95-00137-01}
Corrigendum: Added operational items in
order to eliminate unnecessary restrictions and permissions on stream
attributes. As part of this, representation_clause
was renamed to aspect_clause.
29.k/2
{
8652/0009}
{
AI95-00137-01}
{
AI95-00326-01}
Corrigendum: Added wording to say that the
partial and full views have the same operational and representation aspects.
Ada 2005 extends this to cover all views, including the incomplete view.
29.l/2
{
8652/0040}
{
AI95-00108-01}
Corrigendum: Changed operational items to
have inheritance specified for each such aspect.
29.m/2
{
AI95-00251-01}
Added wording to allow the rejection of types with
progenitors that have conflicting representation items.
29.n/2
{
AI95-00291-02}
The description of the representation of an object
was clarified (with great difficulty reaching agreement). Added wording
to say that representation items on aliased and by-reference objects
never need be supported if they would not be implementable without distributed
overhead even if other recommended level of support says otherwise. This
wording matches the rules with reality.
29.o/3
{
AI95-00444-01}
{
AI05-0005-1}
Added wording so that inheritance depends on whether
operational items are visible rather than whether they occur before the
declaration (we don't want to look into private parts). Limited operational
inheritance to untagged types to avoid anomalies anomolies with private extensions (this is not incompatible, no existing operational
attribute used this capability). Also added wording to clearly define
that subprogram inheritance works like derivation of subprograms.
Incompatibilities With Ada 2005
29.p/3
{
AI05-0106-1}
Correction 2: Specifying
a language-defined aspect for a generic formal parameter is no longer
allowed. Most aspects could not be specified on these anyway; moreover,
this was not allowed in Ada 83, so it is unlikely that compilers are
supporting this as a capability (and it is not likely that they have
a consistent definition of what it means if it is allowed). Thus, we
expect this to occur rarely in existing programs.
Wording Changes from Ada 2005
29.q/3
{
AI05-0009-1}
Correction: Defined that overriding of an
aspect of representation only happens for a non-confirming representation
item. This prevents a derived type from being considered to have only
a confirming representation item when the value would be non-confirming
if given on a type that does not inherit any aspects of representation.
This change just eliminates a wording confusion and ought not change
any behavior.
29.r/3
{
AI05-0112-1}
Correction: Defined a default naming for
representation aspects that are representation pragmas.
29.s/3
{
AI05-0183-1}
Added text ensuring that the rules for representational
and operational items also apply appropriately to aspect_specifications;
generalized operational aspects so that they can be defined for entities
other than types. Any extensions are documented elsewhere.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe