Ada Reference Manual (Ada 2022) — Legal Information

# 13.3 Operational and Representation Attributes

1/1
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.

#### Syntax

2
attribute_definition_clause ::=
for local_name'attribute_designator use expression;
| for local_name'attribute_designator use name;

#### Name Resolution Rules

3
For an attribute_definition_clause that specifies an attribute that denotes a value, the form with an expression shall be used. Otherwise, the form with a name shall be used.
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.

#### Legality Rules

5/3
An attribute_designator is allowed in an attribute_definition_clause only if this Reference Manual explicitly allows it, or for an implementation-defined attribute if the implementation allows it. Each specifiable attribute constitutes an operational aspect or aspect of representation; the name of the aspect is that of the attribute.
6/5
This paragraph was deleted.

#### Static Semantics

7/2
A Size clause is an attribute_definition_clause whose attribute_designator is Size. Similar definitions apply to the other specifiable attributes.
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.1/3
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 at least the storage element and the word. Machine scalars are used to interpret component_clauses when the nondefault bit ordering applies.
9/5
The following representation attributes are defined: Address, Alignment, Size, Object_Size, Storage_Size, Component_Size, Has_Same_Storage, and Overlaps_Storage.
10/1
For a 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.1/3
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.

#### Erroneous Execution

13/3
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.

#### Implementation Advice

14
For an array X, X'Address should point at the first component of the array, and not at the array bounds.
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.
17
An implementation should support Address clauses for imported subprograms.
18/2
This paragraph was deleted.
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.
20
NOTE 1 The specification of a link name with the Link_Name aspect (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
NOTE 2 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.

#### Static Semantics

22/2
For a prefix X that denotes an object:
23/2
X'Alignment
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 is an integral multiple of X'Alignment (that is, the Address modulo the Alignment is zero).
24/2
This paragraph was deleted.
25/2
Alignment 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.
26/2
This paragraph was deleted.
26.1/2
For every subtype S:
26.2/2
S'Alignment
The value of this attribute is of type universal_integer, and nonnegative.
26.3/2
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
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.

#### Erroneous Execution

27
Program execution is erroneous if an Address clause is given that conflicts with the Alignment.
28/2
For an object that is not allocated under control of the implementation, execution is erroneous if the object is not aligned according to its Alignment.

#### Implementation Advice

28.1/3
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
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, subject to the following:
31/5
An implementation is not required to 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.
32/5
An implementation is not required to support a nonconfirming Alignment clause that can cause the creation of an object of an elementary type that cannot be easily loaded and stored by available machine instructions.
32.1/5
An implementation is not required to support an Alignment specified for a derived tagged type that is not a multiple of the Alignment of the parent type. An implementation is not required to support a nonconfirming Alignment specified for a derived untagged by-reference type.
33
The recommended level of support for the Alignment attribute for objects is:
34/2
This paragraph was deleted.
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
For other objects, an implementation should at least support the alignments supported for their subtype, subject to the following:
35.2/5
An implementation is not required to 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.
36
NOTE 3 Alignment is a subtype-specific attribute.
37/2
This paragraph was deleted.
38/3
NOTE 4 A component_clause, Component_Size clause, or specifying the Pack aspect as True can override a specified Alignment.

#### Static Semantics

39/1
For a 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.
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.

#### Implementation Advice

41.1/2
The size of an array object should not include its bounds.
42/5
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 is required to be supported for an aliased elementary object.
43/2
This paragraph was deleted.

#### 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.

#### Implementation Requirements

49
In an implementation, Boolean'Size shall be 1.

#### Implementation Advice

50/5
If the Size of a subtype is nonconfirming and allows for efficient independent addressability (see 9.10) on the target architecture, then the Object_Size of the subtype should have the same value in the absence of an explicit specification of a different value.
Paragraphs 51 and 52 were moved to the Implementation Advice for attribute Object_Size.
53
A Size clause on a composite subtype should not affect the internal layout of components.
54
The recommended level of support for the Size attribute of subtypes is:
55/5
The Size (if not specified) of a static discrete or fixed point subtype should be the number of bits necessary 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.
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.1/2
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/5
An implementation is not required to 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.3/5
A nonconfirming size clause for the first subtype of a derived untagged by-reference type is not required to be supported.
57
NOTE 5 Size is a subtype-specific attribute.
58/3
NOTE 6 A component_clause or Component_Size clause can override a specified Size. Aspect Pack cannot.

#### Static Semantics

58.1/5
For every subtype S:
58.2/5
S'Object_Size
If S is definite, denotes the size (in bits) of a stand-alone aliased object, or a component of subtype S in the absence of an aspect_specification or representation item that specifies the size of the object or component. If S is indefinite, the meaning is implementation-defined. The value of this attribute is of the type universal_integer. If not specified otherwise, the Object_Size of a subtype is at least as large as the Size of the subtype. Object_Size may be specified via an attribute_definition_clause; the expression of such a clause shall be static and its value nonnegative. All aliased objects with nominal subtype S have the size S'Object_Size. In the absence of an explicit specification, the Object_Size of a subtype S defined by a subtype_indication without a constraint, is that of the value of the Object_Size of the subtype denoted by the subtype_mark of the subtype_indication, at the point of this definition.

#### Implementation Advice

58.3/5
If S is a definite first subtype and S'Object_Size is not specified, S'Object_Size should be the smallest multiple of the storage element size larger than or equal to S'Size that is consistent with the alignment of S.
58.4/5
If X denotes an object (including a component) of subtype S, X'Size should equal S'Object_Size, unless:
58.5/5
X'Size is specified; or
58.6/5
X is a nonaliased stand-alone object; or
58.7/5
The size of X is determined by a component_clause or Component_Size clause; or
58.8/5
The type containing component X is packed.
58.9/5
An Object_Size clause on a composite type should not affect the internal layout of components.
58.10/5
The recommended level of support for the Object_Size attribute of subtypes is:
58.11/5
If S is a static signed integer subtype, the implementation should support the specification of S'Object_Size to match the size of any signed integer base subtype provided by the implementation that is no smaller than S'Size. Corresponding support is expected for modular integer subtypes, fixed point subtypes, and enumeration subtypes.
58.12/5
If S is an array or record subtype with static constraints and S is not a first subtype of a derived untagged by-reference type, the implementation should support the specification of S'Object_Size to be any multiple of the storage element size that is consistent with the alignment of S, that is no smaller than S'Size, and that is no larger than that of the largest composite subtype supported by the implementation.
58.13/5
If S is some other subtype, only confirming specifications of Object_Size are required to be supported.

#### Static Semantics

59/1
For a prefix T that denotes a task object (after any implicit dereference):
60/3
T'Storage_Size
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 Storage_Size is specified for the type of the object, the value of the Storage_Size attribute is at least the value determined by the aspect.
61/3
Aspect Storage_Size specifies the amount of storage to be reserved for the execution of a task.
Paragraphs 62 through 65 were moved to Annex J, “Obsolescent Features”.

#### Static Semantics

65.1/3
For a task type (including the anonymous type of a single_task_declaration), the following language-defined representation aspect may be specified:
65.2/3
Storage_Size
The Storage_Size aspect is an expression, which shall be of any integer type.

#### Legality Rules

65.3/3
The Storage_Size aspect shall not be specified for a task interface type.

#### Dynamic Semantics

66/3
When a task object is created, the expression (if any) associated with the Storage_Size aspect of its type is evaluated; the Storage_Size attribute of the newly created task object is at least the value of the expression.
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 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.

#### Implementation Advice

71
The recommended level of support for the Component_Size attribute is:
72/5
An implementation is not required to support specified Component_Sizes that are less than the Size of the component subtype.
73/3
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 is also specified; the implementation should forbid this combination in cases where it cannot support a no-gaps representation.

#### Static Semantics

73.1/3
For a prefix X that denotes an object:
73.2/4
X'Has_Same_Storage
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/4
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. It 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 and the objects occupy at least one bit; otherwise, it returns False.
73.5/3
For a prefix X that denotes an object:
73.6/3
X'Overlaps_Storage
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
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
NOTE 7 X'Has_Same_Storage(Y) implies X'Overlaps_Storage(Y).
73.10/3
NOTE 8 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
The following type-related operational attribute is defined: External_Tag.
74/1
For every subtype S of a tagged type T (specific or class-wide):
75/3
S'External_Tag
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 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.

#### Dynamic Semantics

75.1/3
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.

#### 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.

#### Implementation Permissions

76.1/3
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.
77/2
NOTE 9 The following language-defined attributes are specifiable, at least for some of the kinds of entities to which they apply: Address, Alignment, Bit_Order, Component_Size, External_Tag, Input, Machine_Radix, Output, Read, Size, Small, Storage_Pool, Storage_Size, Stream_Size, and Write.
78
NOTE 10 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.

#### 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
function My_Input(Stream : not null access Ada.Streams.Root_Stream_Type'Class)
return T;
for T'Input use My_Input; -- see 13.13.2
85/5
In the Size clause for Short, fifteen bits is the minimum necessary, since the type definition requires Short'Small <= 2**(–7).

Ada 2005 and 2012 Editions sponsored in part by Ada-Europe