13.7.1 The Package System.Storage_Elements
Static Semantics
1
The following language-defined
library package exists:
2/2
{
AI95-00362-01}
package System.Storage_Elements
is
pragma Pure( Preelaborate(System.Storage_Elements);
3
type Storage_Offset
is range implementation-defined;
4
subtype Storage_Count
is Storage_Offset
range 0..Storage_Offset'Last;
5
type Storage_Element
is mod implementation-defined;
for Storage_Element'Size
use Storage_Unit;
type Storage_Array
is array
(Storage_Offset
range <>)
of aliased Storage_Element;
for Storage_Array'Component_Size
use Storage_Unit;
6
--
{address
(arithmetic)} Address Arithmetic:
7
function "+"(Left : Address; Right : Storage_Offset)
return Address;
function "+"(Left : Storage_Offset; Right : Address)
return Address;
function "-"(Left : Address; Right : Storage_Offset)
return Address;
function "-"(Left, Right : Address)
return Storage_Offset;
8
function "mod"(Left : Address; Right : Storage_Offset)
return Storage_Offset;
9
-- Conversion to/from integers:
10
type Integer_Address
is implementation-defined;
function To_Address(Value : Integer_Address)
return Address;
function To_Integer(Value : Address)
return Integer_Address;
11
pragma Convention(Intrinsic, "+");
-- ...and so on for all language-defined subprograms declared in this package.
end System.Storage_Elements;
11.a
Reason: The Convention pragmas
imply that the attribute Access is not allowed for those operations.
11.b
The mod function is needed so that the
definition of Alignment makes sense.
11.c/2
Implementation defined:
The range of Storage_Elements.Storage_Offset,
the modulus of Storage_Elements.Storage_Element, and the declaration
of Storage_Elements.Integer_Address..
12
Storage_Element represents a storage element. Storage_Offset
represents an offset in storage elements. Storage_Count represents a
number of storage elements.
{contiguous
representation [partial]} {discontiguous
representation [partial]} Storage_Array
represents a contiguous sequence of storage elements.
12.a
Reason: The index subtype of Storage_Array
is Storage_Offset because we wish to allow maximum flexibility. Most
Storage_Arrays will probably have a lower bound of 0 or 1, but other
lower bounds, including negative ones, make sense in some situations.
12.b/2
This paragraph
was deleted.{
AI95-00114-01}
Note that there are some language-defined subprograms
that fill part of a Storage_Array, and return the index of the last element
filled as a Storage_Offset. The Read procedures in Streams (see 13.13.1),
Streams.Stream_IO (see A.12.1), and System.RPC
(see E.5) behave in this manner. These will
raise Constraint_Error if the resulting Last value is not in Storage_Offset.
This implies that the Storage_Array passed to these subprograms should
not have a lower bound of Storage_Offset'First, because then a read of
0 elements would always raise Constraint_Error. A better choice of lower
bound is 1.
13
Integer_Address is a [(signed or modular)] integer
subtype. To_Address and To_Integer convert back and forth between this
type and Address.
Implementation Requirements
14
Storage_Offset'Last shall be greater than or equal
to Integer'Last or the largest possible storage offset, whichever is
smaller. Storage_Offset'First shall be <= (–Storage_Offset'Last).
Implementation Permissions
15/2
This paragraph was
deleted.{
AI95-00362-01}
Package System.Storage_Elements may be declared
pure.
Implementation Advice
16
Operations in System and its children should reflect
the target environment semantics as closely as is reasonable. For example,
on most machines, it makes sense for address arithmetic to “wrap
around.”
{Program_Error (raised
by failure of run-time check)} Operations
that do not make sense should raise Program_Error.
16.a.1/2
Implementation Advice:
Operations in System and its children
should reflect the target environment; operations that do not make sense
should raise Program_Error.
16.a
Discussion: For example, on a segmented
architecture, X < Y might raise Program_Error if X and Y do not point
at the same segment (assuming segments are unordered). Similarly, on
a segmented architecture, the conversions between Integer_Address and
Address might not make sense for some values, and so might raise Program_Error.
16.b
Reason: We considered making Storage_Element
a private type. However, it is better to declare it as a modular type
in the visible part, since code that uses it is already low level, and
might as well have access to the underlying representation. We also considered
allowing Storage_Element to be any integer type, signed integer or modular,
but it is better to have uniformity across implementations in this regard,
and viewing storage elements as unsigned seemed to make the most sense.
16.c
Implementation Note: To_Address is intended
for use in Address clauses. Implementations should overload To_Address
if appropriate. For example, on a segmented architecture, it might make
sense to have a record type representing a segment/offset pair, and have
a To_Address conversion that converts from that record type to type Address.
Extensions to Ada 95
16.d/2
{
AI95-00362-01}
{extensions to Ada 95} Package
System.Storage_Elements is now Pure, so it can be portably used in more
places. (Ada 95 allowed it to be Pure, but did not require that.)