Ada Libraries and Attributes
This is the print version of Ada Libraries and Attributes You won't see this message or any elements not part of the book's content when you print or preview this page. |
The current, editable version of this book is available in Wikibooks, the open-content textbooks collection, at
https://en.wikibooks.org/wiki/Ada_Libraries_and_Attributes
Aspects
editS with Aggregate => (aggregate)
Description
editMechanism to define user-defined aggregates.
with No_Return
Description
editSpecifying the aspect No_Return indicates that a procedure cannot return normally; it may raise an exception, loop forever, or terminate the program.
A non-returning procedure may not contain any return statements. If a non-returning procedure implicitly returns (by reaching the end of its statement sequence), Program_Error will be raised at the point of call.
On the call site, this enables detection of dead code and suppression of warnings about missing return statements or missing assignment to variables.
Example
editprocedure
P ( … )with
No_Return;procedure
Q (x :out
… )is
begin
if
Condthen
P ( … ); Some_Thing_Else; -- This is dead code--and due to No_Return probably a compiler warning!else
x := … ;end
if
; -- No warning about a missing assignment to x hereend
Q;
Portability
editThe aspect No_Return was introduced in Ada 2012. It is the replacement[1] for pragma No_Return which was introduced in Ada 2005.[2]
See also
editWikibook
editAda Reference Manual
editReferences
editwith Ada.Text_IO;
procedure Hello is
begin
Ada.Text_IO.Put_Line("Hello World!");
end Hello;
When entities like variables or subprograms are declared, certain properties thereof normally are left to the compiler to specify (like the size or the address of a variable, the calling convention of a subprogram). Properties which may be queried are called Attributes; those which may be specified are called Aspects. Some aspects correspond with attributes which then have the same name. Aspects and attributes are defined in the Ada Reference Manual Annex K: Language-Defined Aspects and Attributes [Annotated], pragmas in Annex L: Language-Defined Pragmas [Annotated].
Description
editThis language feature has been introduced in Ada 2012.
Aspects are certain properties of an entity that may be specified, depending on the kind of entity, by an aspect specification as part of its declaration or by a separate attribute definition clause or pragma declaration.
Aspect_Specification ::=
with
Aspect_Name [ => Aspect_Definition] {,
Aspect_Name [ => Aspect_Definition] } ;
Attribute_Definition_Clause ::=for
entity_name'attribute_designatoruse
expression; |for
entity_name'attribute_designatoruse
name;
pragma
Name (Parameter_List);
If an aspect is not specified, it depends on the aspect itself whether its value is left to the compiler or prescribed in the Ada RM.
The specification of a Boolean
valued aspect may omit the aspect definition, which then has the value True
.
Examples of such properties are the size of a type, i.e. the number of bits a stand-alone object of that type will use; or that a subprogram will not return from its call: aspect No_Return. This latter one is an example of an aspect that has a Boolean
value.
List of language defined aspects
editIf not marked otherwise, an aspect is specified by an Aspect_Specification.
An aspect marked Ada 2012 is an Ada 2012 language functionality not available in previous Ada generations.
An aspect marked Ada 2022 is an Ada 2022 language functionality not available in previous Ada generations.
Aspects not so marked, were previously defined via pragmas or attribute definition clauses. This is still possible, but deprecated.
A – D
edit- Aggregate (Ada 2022; Aspect_Specification)
- Address (Attribute_Definition_Clause, Aspect_Specification)
- Alignment (Attribute_Definition_Clause)
- All_Calls_Remote (Pragma)
- Allows_Exit (Ada 2022; Aspect_Specification)
- Asynchronous
- Atomic
- Atomic_Components
- Attach_Handler
- Bit_Order (Attribute_Definition_Clause)
- Coding (Enumeration_Representation_Clause)
- Component_Size (Attribute_Definition_Clause)
- Constant_Indexing (Ada 2012)
- Convention
- CPU (Ada 2012)
- Default_Component_Value (Ada 2012)
- Default_Initial_Condition (Ada 2022; Aspect_Specification)
- Default_Iterator (Ada 2012)
- Default_Storage_Pool (Ada 2012; Pragma)
- Default_Value (Ada 2012)
- Dispatching (Ada 2022; Aspect_Specification)
- Dispatching_Domain (Ada 2012)
- Discard_Names (Ada 2012; Aspect_Specification, Pragma)
- Dynamic_Predicate (Ada 2012)
E – O
edit- Elaborate_Body (Pragma)
- Exclusive_Functions (Ada 2012)
- Export
- External_Name
- External_Tag (Attribute_Definition_Clause)
- Full_Access_Only (Ada 2022; Aspect_Specification)
- Global (Ada 2022; Aspect_Specification)
- Global'Class (Ada 2022; Aspect_Specification)
- Implicit_Dereference (Ada 2012)
- Import
- Independent (Ada 2012)
- Independent_Components (Ada 2012)
- Inline
- Input (Attribute_Definition_Clause)
- Input'Class (Ada 2012; Attribute_Definition_Clause)
- Integer_Literal (Ada 2022; Aspect_Specification)
- Interrupt_Handler
- Interrupt_Priority
- Iterator_Element (Ada 2012)
- Iterator_View (Ada 2022; Aspect_Specification)
- Layout (Record_Representation_Clause)
- Link_Name
- Machine_Radix (Attribute_Definition_Clause)
- Max_Entry_Queue_Length (Ada 2022; Aspect_Specification)
- No_Controlled_Parts (Ada 2022; Aspect_Specification)
- No_Return
- Nonblocking (Ada 2022; Aspect_Specification)
- Output (Attribute_Definition_Clause)
- Output'Class (Ada 2012; Attribute_Definition_Clause)
P – Z
edit- Pack
- Parallel_Calls (Ada 2022; Aspect_Specification)
- Parallel_Iterator (Ada 2022; Aspect_Specification)
- Post (Ada 2012)
- Post'Class (Ada 2012)
- Pre (Ada 2012)
- Pre'Class (Ada 2012)
- Predicate_Failure (Ada 2012)
- Preelaborate (Pragma)
- Preelaborable_Initialization (Ada 2022; Aspect_Specification)
- Priority
- Pure (Pragma)
- Put_Image (Ada 2022; Aspect_Specification)
- Read (Attribute_Definition_Clause)
- Read'Class (Ada 2012; Attribute_Definition_Clause)
- Real_Literal (Ada 2022; Aspect_Specification)
- Relative_Deadline (Ada 2022; Aspect_Specification)
- Remote_Call_Interface (Pragma)
- Remote_Types (Pragma)
- Shared_Passive (Pragma)
- Size (Attribute_Definition_Clause)
- Small (Attribute_Definition_Clause)
- Stable_Properties (Ada 2022; Aspect_Specification)
- Stable_Properties'Class (Ada 2022; Aspect_Specification)
- Static (Ada 2022; Aspect_Specification)
- Static_Predicate (Ada 2012)
- Storage_Pool (Attribute_Definition_Clause)
- Storage_Size (Attribute_Definition_Clause)
- Stream_Size (Attribute_Definition_Clause)
- String_Literal (Ada 2022; Aspect_Specification)
- Synchronization (Ada 2012)
- Type_Invariant (Ada 2012)
- Type_Invariant'Class (Ada 2012)
- Unchecked_Union (Ada 2022; Aspect_Specification)
- Use_Formal (Ada 2022; Aspect_Specification)
- Variable_Indexing (Ada 2012)
- Volatile
- Volatile_Components
- Write (Attribute_Definition_Clause)
- Write'Class (Ada 2012; Attribute_Definition_Clause)
- Yield (Ada 2022; Aspect_Specification)
List of implementation defined aspects
editThe following pragmas are not available in all Ada compilers, only in those that had implemented them.
Currently, there are only listed the implementation-defined pragmas of a few compilers. You can help Wikibooks adding specific aspects of other compilers:
- GNAT
- Implementation defined aspect of the GNAT compiler from AdaCore and FSF.
- Ada_2005 (GNAT)
- Ada_2012 (GNAT)
- Favor_Top_Level (GNAT)
- Inline_Always (GNAT)
- Object_Size (GNAT)
- Persistent_BSS (GNAT)
- Pure_Function (GNAT)
- Remote_Access_Type (GNAT)
- Shared (GNAT)
- Suppress_Debug_Info (GNAT)
- Test_Case (GNAT)
- Universal_Aliasing (GNAT)
- Unmodified (GNAT)
- Unreferenced (GNAT)
- Unreferenced_Objects (GNAT)
- Value_Size (GNAT)
- Warnings (GNAT)
See also
editWikibook
editAda Reference Manual
editAda 2012
edit- 13.1.1: Aspect Specifications [Annotated]
- K.1: Language-Defined Aspects [Annotated]
- J.15: Aspect-related Pragmas [Annotated]
Ada 2022
editReferences
edit
Ada Programming/Aspects/Aggregate
editS with Aggregate => (aggregate)
Description
editMechanism to define user-defined aggregates.
Ada Programming/Aspects/No Return
edit
with No_Return
Description
editSpecifying the aspect No_Return indicates that a procedure cannot return normally; it may raise an exception, loop forever, or terminate the program.
A non-returning procedure may not contain any return statements. If a non-returning procedure implicitly returns (by reaching the end of its statement sequence), Program_Error will be raised at the point of call.
On the call site, this enables detection of dead code and suppression of warnings about missing return statements or missing assignment to variables.
Example
editprocedure
P ( … )with
No_Return;procedure
Q (x :out
… )is
begin
if
Condthen
P ( … ); Some_Thing_Else; -- This is dead code--and due to No_Return probably a compiler warning!else
x := … ;end
if
; -- No warning about a missing assignment to x hereend
Q;
Portability
editThe aspect No_Return was introduced in Ada 2012. It is the replacement[1] for pragma No_Return which was introduced in Ada 2005.[2]
See also
editWikibook
editAda Reference Manual
editReferences
editAda Programming/Aspects/Write
editwith Ada.Text_IO;
procedure Hello is
begin
Ada.Text_IO.Put_Line("Hello World!");
end Hello;
Attributes
editAda Programming/Attributes/'Abort Signal
editDescription
editProvides the entity for the special exception used to signal task abort or asynchronous transfer of control. Normally this attribute should only be used in the tasking runtime (it is highly peculiar, and completely outside the normal semantics of Ada, for a user program to intercept the abort exception).
Example
editStandard'Abort_Signal
(Standard
is the only allowed prefix).
Ada Programming/Attributes/'Access
edit
Description
editX'Access is an Ada attribute where X is any object or subprogram.
'Access may be used to return an access value designating the object or subprogram.
Example
edittype
General_Pointeris
access
all
Integer;type
Constant_Pointeris
access
constant
Integer; I1:aliased
constant
Integer := 10; I2:aliased
Integer; P1: General_Pointer := I1'Access; -- illegal P2: Constant_Pointer := I1'Access; -- OK, read only P3: General_Pointer := I2'Access; -- OK, read and write P4: Constant_Pointer := I2'Access; -- OK, read only P5:constant
General_Pointer := I2'Access; -- read and write only to I2
type
Callback_Procedureis
access
procedure
(Id : Integer; Text: String);procedure
Process_Event (Id : Integer; Text: String); My_Callback: Callback_Procedure := Process_Event'Access;
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Address
edit
Attribute Definition Clause
editX'Address is an Ada attribute where X is any object, program unit, or label, RM 13.3(10/1). [A program unit is either a package, a task unit, a protected unit, a protected entry, a generic unit, or an explicitly declared subprogram other than an enumeration literal, RM 10.1(1).]
'Address may be used to return the address of the first element allocated to X. 'Address may also be used to set the address of X for stand-alone objects and program units, RM 13.3(12).
-- A 32 bit hardware register Device_Input_Value: Interfaces.Unsigned_32;for
Device_Input_Value'Addressuse
System.Storage_Elements.To_Address (16#8000_05C4#);
It's not recommended to use Integer_32 in this case.
Aspect Specification
editThe address may also be specified directly when declaring the variable using an aspect declaration:
Device_Input_Value : Interfaces.Unsigned_32 with Address => System.Storage_Elements.To_Address (16#8000_05C4#);
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Address Size
editDescription
editIs a static constant giving the number of bits in an Address
. It is the same value as System.Address’Size, but has the advantage of being static, while a direct reference to System.Address’Size is nonstatic because Address is a private type.
Example
editStandard'Address_Size
(Standard
is the only allowed prefix)
Ada Programming/Attributes/'Adjacent
edit
Description
editS'Adjacent(X, T) is an Ada attribute where X is any floating point type.
'Adjacent returns the adjacent floating point number to X in the direction of T.
Example
editwith Ada.Text_IO; procedure Adjacent is package T_IO renames Ada.Text_IO; package F_IO is new Ada.Text_IO.Float_IO (Float); X : Float := 1.0; begin T_IO.Put (" X = "); F_IO.Put(Item => X, Aft => 10, Exp => 0); T_IO.New_Line; T_IO.Put ("Float'Adjacent(X, Float'First) = "); F_IO.Put(Item => Float'Adjacent(X, Float'First), Aft => 10, Exp => 0); T_IO.New_Line; T_IO.Put ("Float'Adjacent(X, Float'Last) = "); F_IO.Put(Item => Float'Adjacent(X, Float'Last), Aft => 10, Exp => 0); T_IO.New_Line; end Adjacent;
The output with GNAT 4.6 on the x86-64 architecture is:
X = 1.0000000000 Float'Adjacent(X, Float'First) = 0.9999999404 Float'Adjacent(X, Float'Last) = 1.0000001192
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Aft
editS'Aft is an Ada attribute where S is a fixed point subtype.
S'Aft returns the number digits needed after the decimal point to accommodate the precision of the subtype S, unless the delta of the subtype S is larger than 0.1, in which case the attribute returns a value of 1.
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Alignment
edit
Description
editX'Alignment is an Ada attribute where X is any memory-allocated object or type. This attribute controls the address values used for objects. The alignment must be non-negative. A value of zero means that the object need not be allocated at the boundary of a storage units. Otherwise the address is a multiple of X's alignment.
The alignment of an object may be set.
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Asm Input
editDescription
editThe Asm_Input
attribute denotes a function that takes two parameters. The first is a string, the second is an expression of the type designated by the prefix. The first (string) argument is required to be a static expression, and is the constraint for the parameter, (e.g., what kind of register is required). The second argument is the value to be used as the input argument. The possible values for the constant are the same as those used in the RTL, and are dependent on the configuration file used to built the GCC back end.
Example
editAda Programming/Attributes/'Asm Output
editDescription
editThe Asm_Output
attribute denotes a function that takes two parameters. The first is a string, the second is the name of a variable of the type designated by the attribute prefix. The first (string) argument is required to be a static expression and designates the constraint for the parameter (e.g., what kind of register is required). The second argument is the variable to be updated with the result. The possible values for constraint are the same as those used in the RTL, and are dependent on the configuration file used to build the GCC back end. If there are no output operands, then this argument may either be omitted, or explicitly given as No_Output_Operands
.
Example
editAda Programming/Attributes/'Atomic Always Lock Free
editDescription
editThe prefix of the Atomic_Always_Lock_Free
attribute is a type. The result indicates whether atomic operations are supported by the target for the given type.
Ada Programming/Attributes/'Base
edit
Description
editRepresents the base type of another type or subtype. This attribute is used to access attributes of the base type.
T'Base refers to the "base range" of the type, which defines the range in which intermediate calculations are performed.
Base for Integer Types
editThe standard states that the range of T'Base:
- includes the value 0
- is symmetric about zero, with possibly an extra negative value
- includes all of the values in the subtype T
So for example, if T is:
type
Tis
range
1 .. 42;
then the compiler will choose a hardware supported type that includes this range, in this case probably an eight bit type (on a two's complement machine)
type
T'Baseis
range
-128 .. 127;
This definition is not to be taken literally, as by Ada semantics, T and T'Base would be incompatible. In effect, the declaration of T would then be
subtype
Tis
T'Baserange
1 .. 42;
Note that built-in operators go through the base type, and T's "+" op for example is implicitly declared as:
function
"+" (L, R : T'Base)return
T'Base;
There are no constraint checks on T'Base, so for example:
declare
O1 : T := T'(1) + T'(2); O2 : T'Base := T'(1) + T'(2);begin
then in the first assignment to O1, there is a constraint check to ensure that the result of 1 + 2 is in the range of T, but in the second assignment to O2, there is no check.
T'Base is useful for generics, when you need to be able to recover the base range of the type, in order to declare an object with value 0; for example, if this is an accumulator.
It is helpful to know something about the base range of the type, so that you have a guarantee that you don't get any overflow during intermediate calculations. For example, given type T above then:
procedure
Op (O1, O2 : T)is
Sum : T'Base := O1 + O2;begin
This is a problem, since if the sum of O1 and O2 is large (that is, greater than T'Base'Last), then you'll get overflow. Knowing that you're going to be adding two values together means you should declare the type this way:
T_Last :constant
:= 42;type
T_Baseis
0 .. 2 * T_Last;subtype
Tis
T_Baserange
1 .. T_Last;
That way you know that (sub)type T's range is 1 .. 42, but you also have a guarantee that T'Base'Last >= 84, and hence the sum of two values of type T cannot overflow.
Note that a declaration of the form:
type
Tis
range
...
actually declares a subtype, named T, of some anonymous base type. We can refer to the range of this base type as T'Base.
Base for Enumeration Types
editAn enumeration type is its own base type, so given this type:
type
ETis
(A, B, C);
then the range of ET is the same as the range of ET'Base. If you need some extra literals in your "base" type, then you have to declare them manually, not unlike what we did above:
type
ET_Baseis
(ET_Base_First, A, B, C, ET_Base_Last);subtype
ETis
ET_Baserange
A .. C;
Now you can say ET'Succ (ET'Last) and you'll get a meaningful answer. This is necessary when you do something like:
declare
E : ET'Base := ET'First;begin
while
E <= ET'Lastloop
... -- do something E := ET'Succ (E);end
loop
;end
;
Also when you derive from ET_Base with a range constraint, the base of the derived type will include all values of the base type:
type
New_ETis
new
ET_Baserange
A .. C; Correct:constant
Boolean := New_ET'Base'First = ET_Base_First;
Note that here ET_BASE_First is of type New_ET.
Example
editIf you declare:
type
My_Enumis
(Enum1, Enum2, Enum3);
and
subtype
Sub_Enumis
My_Enumrange
Enum1 .. Enum2;
then Sub_Enum'Base'Last is Enum3.
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Bit
editDescription
editobj'Bit
, where obj
is any object, yields the bit offset within the storage unit (byte) that contains the first bit of storage allocated for the object. The value of this attribute is of the type universal_integer and is always a nonnegative number smaller than System.Storage_Unit
.
For an object that is a variable or a constant allocated in a register, the value is zero. (The use of this attribute does not force the allocation of a variable to memory).
For an object that is a formal parameter, this attribute applies to either the matching actual parameter or to a copy of the matching actual parameter.
For an access object the value is zero. Note that obj.all'Bit
is subject to an Access_Check
for the designated object. Similarly for a record component X.C'Bit
is subject to a discriminant check and X(I).Bit
and X(I1..I2)'Bit
are subject to index checks.
This attribute is designed to be compatible with the DEC Ada 83 definition and implementation of the Bit
attribute.
Example
editAda Programming/Attributes/'Bit Order
edit
Description
editR'Bit_Order is a representation attribute used to specify the bit numbering of a record representation clause (for a record type). The bit ordering is of type System.Bit_Order, and may be either:
- High_Order_First when the bit 0 is the most significant bit
- Low_Order_First when the bit 0 is the least significant bit
assuming the bit sequence is interpreted as an integer value. The constant System.Default_Bit_Order represents the native bit numbering of the platform.
It is worth noting that the bit ordering only affects the bit numbering for a record representation clause, and not the byte order of its (multibyte) fields. [1]
Introduction
editStorage units are ordered by their addresses. Let's look at an integer occupying several bytes (let's assume a byte being 8 bits for this discussion).
- On a big endian (BE) machine, the integer's most significant byte is stored at the least address.
- On a little endian (LE) machine, its least significant byte is stored at the least address.
So in order to be able to count bits consecutively across byte boundaries, Ada counts bits within a byte according to the endianness from most significant bit (MSB) 0 to least significant bit (LSB) on BE and the other way round on LE.[2]
This is how it looks (conveniently writing left to right on BE, right to left on LE):
BE Byte 0 1 2 … (counting bytes, i.e. addresses, left to right; higher addresses to the right) LE Byte … 2 1 0 (counting bytes right to left; higher addresses to the left) MSB LSB BE Bit 0 1 2 3 4 5 6 7 (counting bits within a byte left to right) LE Bit 7 6 5 4 3 2 1 0 (counting bits right to left)
We're used to writing left to right, but for LE, as you can see, it's convenient to write addresses from right to left. So on BE, a sequence of bytes and bits is counted like this:
Byte 00 01 02 Bit 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 … 00 01 02 03 04 05 06 07 08 09 10 11 12 13 … (we can equally begin to count at byte 01)
In order to be able to write and count consecutively on LE, we have to write right to left like for example in the Arabian or Hebrew scripts (the MSB is always on the left; this seems to be a global trait in all modern scripts):
Byte 02 01 00 Bit … 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 … 13 12 11 10 09 08 07 06 05 04 03 02 01 00
In a record representation like the following (of course only one of the two lines specifying X may be present)
for T use record X at 0 range 13 .. 17; -- these two lines… X at 1 range 5 .. 9; -- … are equivalent end record;
the component X occupies the bits shown in boldface. The byte number (0 resp. is 1) is called Position, the bounds are called First_Bit (13 resp. 5) and Last_Bit (17 resp. 9); there are corresponding attributes 'Position, 'First_Bit and 'Last_Bit. (The meaning of the component X is irrelevant here, only its size is relevant.) As you can see, X is a crossborder component. Thus the result of applying the attribute 'Bit_Order to a record with crossborder components depends on the Ada generation.
Ada 95
editAda 95 defines the result of the attribute for the non-native bit order only when applied within a storage unit or when an item completely fills a sequence of storage units. By applying the attribute to a record, we force the compiler to count bits in the indicated manner, independent of the machine architecture.
type
Recis
record
Aat
0range
0 .. 5; Bat
0range
6 .. 7;end
record
;for
Rec'Bit_Orderuse
High_Order_First;
The component B occupies the bits shown in boldface:
Byte 0 Bit 0 1 2 3 4 5 6 7
The layout of this record will be the same on BE and on LE machines, i.e. the representation is endian-independent.
We could equally well have defined this record like so and arrived at the same endian-independent layout:
type
Recis
record
Aat
0range
2 .. 7; Bat
0range
0 .. 1;end
record
;for
Rec'Bit_Orderuse
Low_Order_First;
Byte 0 Bit 7 6 5 4 3 2 1 0
However a record like the following, where B is crossborder, is only valid on a BE machine, i.e. in the native bit order.
type
Recis
record
Aat
0range
0 .. 5; Bat
0range
6 .. 9;end
record
;for
Rec'Bit_Orderuse
High_Order_First;
Byte 0 1 Bit 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 # 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
Compiled on a LE machine, the compiler will complain that B occupies non-contiguous storage and reject the code, since the byte order is not affected by the attribute (remember, the next byte with bit numbers 8 to 15 has to be put on the left):
Byte 1 0 Bit 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07 # 08 09 10 11 12 13 14 15 00 01 02 03 04 05 06 07
As an example of a record where items fill a range of complete storage units take:
type
Recis
record
Aat
0range
0 .. 7; Bat
1range
0 .. 15;end
record
;for
Rec'Bit_Orderuse
High_Order_First;
This is valid on both architectures leading to the layout:
BE 0 1 2 Bit 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
LE 2 1 0 Bit 08 09 10 11 12 13 14 15 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07
where A fills the bits in normal face, B those in bold face. As you can see, it doesn't matter that bits are counted in this strange way on LE since component B fills its two bytes completely.
Ada 2005
editFor the native bit order, there is no change. Record representation specifications have worked since Ada 83. Only the attribute 'Bit_Order has been introduced in Ada 95 with the restrictions as shown above.
In order to improve the situation for non-native bit orders, Ada 2005 introduces the notion of machine scalars. A machine scalar is a conceptual hardware based unsigned integer within which bits are counted and the components positioned as requested.
We need a more elaborated record example now (the values returned by the corresponding attributes 'Position, 'First_ and 'Last_Bit (in native bit order) are given as comments; note that the bit numbers returned are always counted starting with the byte in which the component begins):
for
Tuse
record
Iat
0range
0 .. 15; -- at 0 range 0 .. 15 Aat
2range
0 .. 12; -- at 2 range 0 .. 12 Bat
2range
13 .. 17; -- at 3 range 5 .. 9 Cat
2range
18 .. 23; -- at 4 range 2 .. 7 Dat
5range
0 .. 7; -- at 5 range 0 .. 7end
record
;
Let's assume I is a 16 bit (signed or unsigned) integer, the other components are of some unspecified types with the given size requirements. The complete record's size is 48. This is how it looks like on BE and LE machines:
Byte 0 1 2 3 4 5 BE 012345678901234501234567890123456789012301234567 IIIIIIIIIIIIIIIIAAAAAAAAAAAAABBBBBCCCCCCDDDDDDDD DDDDDDDDCCCCCCBBBBBAAAAAAAAAAAAAIIIIIIIIIIIIIIII LE 765432103210987654321098765432105432109876543210 Byte 5 4 3 2 1 0
In the following, we're going to show how far we can go to reach endian-independence of the representation. The result will be that we only have to swap bytes after transfer from one architecture to the other when the new Ada 2005 features are used correctly.
For the following, we'll assume that we are on a big-endian machine, so that we append the corresponding attribute to the representation:
for
Tuse
record
Iat
0range
0 .. 15; Aat
2range
0 .. 12; Bat
2range
13 .. 17; Cat
2range
18 .. 23; Dat
5range
0 .. 7;end
record
;for
T'Bit_Orderuse
High_Order_First;
When this is compiled on a little-endian machine, all components with the same Position are taken together and put in a matching machine scalar. The machine scalar is positioned at the given Position, but inside the bits are counted from the opposite side.
Let's take the first component, I. It uses 16 bits, so a 16 bit machine scalar will do. It is positioned at byte 0, but inside the compiler will count from the high order bit side. This is how it looks (NNBO - non-native bit order):
IIIIIIIIIIIIIIII NNBO 0123456789012345 Byte 5 4 3 2 1 0
Now to the next Position 2. The respective components A, B, C use together three bytes, so a 32 bit machine scalar is needed. It is positioned at byte 2, and inside the count will again start from the opposite side. This is how it looks:
IIIIIIIIIIIIIIII NNBO 012345678901234567890123456789010123456789012345 Byte 5 4 3 2 1 0
The bit count starts at the high order bit of byte 5 and continues down to the low order bit of byte 2. The components A, B, C are positioned inside this scalar according to the respective ranges. Thus we arrive at this layout:
AAAAAAAAAAAAABBBBBCCCCCC IIIIIIIIIIIIIIII NNBO 012345678901234567890123456789010123456789012345 Byte 5 4 3 2 1 0
We immediately see the conflict with component D, whose range is already occupied by A, and the compiler will of course complain and reject the code. The solution is simple: Just instead of locating D at Position 5, we change this to the (on BE) equivalent line like so:
for
Tuse
record
Iat
0range
0 .. 15; Aat
2range
0 .. 12; Bat
2range
13 .. 17; Cat
2range
18 .. 23; --D at 5 range 0 .. 7; Dat
2range
24 .. 31;end
record
;for
T'Bit_Orderuse
High_Order_First;
And, drum roll, on LE, we now have (for comparison, the native layout is also given):
AAAAAAAAAAAAABBBBBCCCCCCDDDDDDDDIIIIIIIIIIIIIIII NNBO 012345678901234567890123456789010123456789012345 Byte 5 4 3 2 1 0 IIIIIIIIIIIIIIIIAAAAAAAAAAAAABBBBBCCCCCCDDDDDDDD BE 012345678901234501234567890123456789012345678901 Byte 0 1 2 3 4 5
In the non-native bit order, the values returned by the corresponding attributes 'Position, 'First_ and 'Last_Bit are exactly those given in the record specification.
As an additional service, GNAT's compilation output will give you the values as counted in the native bit order within the machine scalar:
range "I" 0 .. 15 "A" 19 .. 31 "B" 14 .. 18 "C" 8 .. 13 "D" 0 .. 7 AAAAAAAAAAAAABBBBBCCCCCCDDDDDDDDIIIIIIIIIIIIIIII NNBO 012345678901234567890123456789010123456789012345 LE 109876543210987654321098765432105432109876543210 Byte 5 4 3 2 1 0
This is as far as we can get with the current Ada standard.
Data Transfer
editLet us transfer a value of this record from the native big-endian machine to a little-endian machine. For demonstration purposes, the high-order parts of the crossborder items are shown in upper case, the low-order parts in lower case.
IIIIIIIIiiiiiiiiAAAAAAAAaaaaaBBBbbCCCCCCDDDDDDDD BE 012345678901234501234567890123456789012345678901 Byte 0 1 2 3 4 5
The bytes will be transferred in the given order. Since the bit order attribute does not reorder the bytes after transfer, on the target machine we will receive the data in scrambled order:
DDDDDDDDbbCCCCCCaaaaaBBBAAAAAAAAiiiiiiiiIIIIIIII NNBO 012345678901234567890123456789010123456789012345 Byte 5 4 3 2 1 0
All we have to do to arrive at the desired end, is to swap bytes 0↔1, 2↔5, 3↔4:
AAAAAAAAaaaaaBBBbbCCCCCCDDDDDDDDIIIIIIIIiiiiiiii NNBO 012345678901234567890123456789010123456789012345 Byte 5 4 3 2 1 0
Example
editThe following two sets of representation clauses specify the same register layout in any machine / compiler (Ada 2005 and later):
type
Device_Registeris
record
Ready : Status_Flag; Error : Error_Flag; Data : Unsigned_16;end
record
;for
Device_Registeruse
record
Readyat
0range
0 .. 0; Errorat
0range
1 .. 1; -- Reserved bits Dataat
0range
16 .. 31;end
record
;for
Device_Register'Sizeuse
32;for
Device_Register'Bit_Orderuse
System.Low_Order_First;pragma
Atomic (Device_Register);
If the bit order is modified, the bit numbering of all the elements of the record representation clause must be reversed:
type
Device_Registeris
record
Ready : Status_Flag; Error : Error_Flag; Data : Unsigned_16;end
record
;for
Device_Registeruse
record
Readyat
0range
31 .. 31; -- Bit numbering has changed Errorat
0range
30 .. 30; -- Bit numbering has changed -- Reserved bits Dataat
0range
0 .. 15; -- Bit numbering has changed (but byte order is not affected)end
record
;for
Device_Register'Sizeuse
32;for
Device_Register'Bit_Orderuse
System.High_Order_First; -- Reverse bit orderpragma
Atomic (Device_Register);
Both can be interchangeably used in the same machine. But note that in two machines with different endianness the Data field will have the native byte order regardless of the bit order specified in the representation clauses.
Incorrect Usage
editThe 'Bit_Order attribute is not intended to convert data between a big-endian and a little-endian machine (it affects bit numbering, not byte order). The compiler will not generate code to reorder multi-byte fields when a non-native bit order is specified.[3][4][5]
References
edit- ↑ Note that when the ARM talks about "big endian" and "little endian" in the definition of the 'Bit_Order attribute it really means bit endianness, not byte endianness. (Nowadays the term endianness is usually reserved for talking about byte order, although it can also be used for bit numbering.) Thus, in this context, when the ARM says "little endian" it refers to "LSB 0", and when it says "big endian" this is the same as "MSB 0":
«High_Order_First (known in the vernacular as “big endian”) means that the first bit of a storage element (bit 0) is the most significant bit (interpreting the sequence of bits that represent a component as an unsigned integer value). Low_Order_First (known in the vernacular as “little endian”) means the opposite: the first bit is the least significant.» [LRM, §13.5.3(2)]
- ↑ ISO/IEC 8652:1987. "13.4 Record Representation Clauses". Ada 83 Reference Manual.
The range defines the bit positions of the storage place, relative to the storage unit. The first storage unit of a record is numbered zero. The first bit of a storage unit is numbered zero. The ordering of bits in a storage unit is machine_dependent and may extend to adjacent storage units.
{{cite book}}
: Unknown parameter|chapterurl=
ignored (|chapter-url=
suggested) (help) - ↑ AI95-00133-01 (1996-05-07). "Controlling bit ordering". Class: binding interpretation. Ada Rapporteur Group.
Bit_Order clauses are concerned with the numbering of bits and not concerned with data flipping interoperability.
- ↑ ISO/IEC 8652:2007. "13.5.3 Bit Ordering (9/2)". Ada 2005 Reference Manual. Retrieved 2008-06-02.
Bit_Order clauses make it possible to write record_representation_clauses that can be ported between machines having different bit ordering. They do not guarantee transparent exchange of data between such machines.
{{cite book}}
: Unknown parameter|chapterurl=
ignored (|chapter-url=
suggested) (help) - ↑ Thomas Quinot (2013). "Gem #140: Bridging the Endianness Gap". AdaCore. Retrieved 2013-01-31.
the order in which the bytes that constitute machine scalars are written to memory is not changed by the Bit_Order attribute -- only the indices of bits within machine scalars are changed.
{{cite web}}
: Unknown parameter|month=
ignored (help)
Interfacing
editRecord representation clauses are a unique feature of the Ada language as far as the authors know, so there is no need to have a feature similar to attribute 'Bit_Order in other programming languages. It is common practice in other programming languages to use masks and bit operations explicitly, thus the native bit numbering must always be used.
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Attributes/'Position
- 'First_Bit
- 'Last_Bit
Ada Reference Manual
editAda Rationale
edit- Ada 95: 13.1 Representation of Data
- Ada 2005: 9.2.1 Incompatibilities with original Ada 95
References and notes
editFurther reading
edit- Norman H. Cohen (1994). "Endian-independent record representation clauses" (PDF). ACM SIGAda Ada Letters. New York, NY, USA: Association for Computing Machinery. XIV (1): 27–29. ISSN 1094-3641. Retrieved 2008-12-20.
- Randal P. Andress (2005). "Wholesale byte reversal of the outermost Ada record object to achieve endian independence for communicated data types" (PDF). ACM SIGAda Ada Letters. New York, NY, USA: Association for Computing Machinery. XXV (3): 19–27. ISSN 1094-3641. Retrieved 2008-12-20.
Ada Programming/Attributes/'Bit Order:3
editThe 'Bit_Order attribute is not intended to convert data between a big-endian and a little-endian machine (it affects bit numbering, not byte order). The compiler will not generate code to reorder multi-byte fields when a non-native bit order is specified.[1][2][3]
References
edit- ↑ AI95-00133-01 (1996-05-07). "Controlling bit ordering". Class: binding interpretation. Ada Rapporteur Group.
Bit_Order clauses are concerned with the numbering of bits and not concerned with data flipping interoperability.
- ↑ ISO/IEC 8652:2007. "13.5.3 Bit Ordering (9/2)". Ada 2005 Reference Manual. Retrieved 2008-06-02.
Bit_Order clauses make it possible to write record_representation_clauses that can be ported between machines having different bit ordering. They do not guarantee transparent exchange of data between such machines.
{{cite book}}
: Unknown parameter|chapterurl=
ignored (|chapter-url=
suggested) (help) - ↑ Thomas Quinot (2013). "Gem #140: Bridging the Endianness Gap". AdaCore. Retrieved 2013-01-31.
the order in which the bytes that constitute machine scalars are written to memory is not changed by the Bit_Order attribute -- only the indices of bits within machine scalars are changed.
{{cite web}}
: Unknown parameter|month=
ignored (help)
Ada Programming/Attributes/'Bit Position
editDescription
editR.C'Bit_Position
, where R
is a record object and C
is one of the fields of the record type, yields the bit offset within the record contains the first bit of storage allocated for the object. The value of this attribute is of the type universal_integer. The value depends only on the field C
and is independent of the alignment of the containing record R
.
Example
editAda Programming/Attributes/'Body Version
editDescription
editYields a value of the predefined type String that identifies the version of the compilation unit (P) that contains the body (but not any subunits) of the program unit.
Example
editP’Body_Version return String
Ada Programming/Attributes/'Callable
edit
Description
editX'Callable is an Ada attribute where X is any task object. If the task is completed or has been terminated, this attribute is false. Otherwise, this attribute is true (i.e. the task is callable).
Be warned - calling X'Callable can result in a race condition. X'Callable may be true at the time the attribute value is read, but it may become false at the time action is taken based on the value read. Once X'Callable is false, however, it can be expected to stay false.
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Caller
editDescription
editIdentifies the task whose call is now being serviced. Yields a value of the type Task_Id that identifies the task whose call is now being serviced.
Use of this attribute is allowed only inside an accept_statement, or entry_body after the entry_barrier, corresponding to the entry_declaration denoted by E.
Example
editE’Caller return Task_ID
Ada Programming/Attributes/'Ceiling
edit
Description
editX'Ceiling(Y) is an Ada attribute where X is any floating-point type and Y is any instance of that type. This attribute represents the smallest integer value that is greater than or equal to Y.
Example
editX : Float := 1.5; Y : Float := 1.0; Z : Float := 1.999; ...pragma
Assert (Float'Ceiling(X) = 2.0 ); -- OKpragma
Assert (Float'Ceiling(Y) = 1.0 ); -- OKpragma
Assert (Float'Ceiling(Z) = 1.0 ); -- Wrong
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Attributes/'Floor
- Ada Programming/Attributes/'Rounding
- Ada Programming/Attributes/'Unbiased_Rounding
Ada Reference Manual
editAda Programming/Attributes/'Class
edit
The Class attribute denotes the class wide type of the given tagged type.
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Code Address
editDescription
edit
The 'Address
attribute may be applied to subprograms in Ada 95 and Ada 2005, but the intended effect seems to be to provide an address value which can be used to call the subprogram by means of an address clause as in the following example:
procedure K is ...
procedure L;
for L'Address use K'Address;
pragma Import (Ada, L);
A call to L
is then expected to result in a call to K
. In Ada 83, where there were no access-to-subprogram values, this was a common work-around for getting the effect of an indirect call. GNAT implements the above use of Address
and the technique illustrated by the example code works correctly.
However, for some purposes, it is useful to have the address of the start of the generated code for the subprogram. On some architectures, this is not necessarily the same as the Address
value described above. For example, the Address
value may reference a subprogram descriptor rather than the subprogram itself.
The 'Code_Address
attribute, which can only be applied to subprogram entities, always returns the address of the start of the generated code of the specified subprogram, which may or may not be the same value as is returned by the corresponding 'Address
attribute.
Example
editAda Programming/Attributes/'Compiler Version
editDescription
editStandard'Compiler_Version
(Standard
is the only allowed prefix) yields a static string identifying the version of the compiler being used to compile the unit containing the attribute reference.
Ada Programming/Attributes/'Component Size
edit
Description
editR'Component_Size is a representation attribute used to get the number of bits of each component of an array object or type.
The 'Component_Size attribute may also be used in representation clauses to specify the size in bits used to store each component of an array type.
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Attributes/'Size
- Ada Programming/Attributes/'Max_Size_In_Storage_Elements
- Ada Programming/Attributes/'Value_Size (implementation defined)
- Ada Programming/Attributes/'Object_Size (implementation defined)
Ada 95 Reference Manual
edit- 13.3: Operational and Representation Attributes [Annotated]
- Annex K: Language-Defined Attributes [Annotated]
Ada 2005 Reference Manual
edit- 13.3: Operational and Representation Attributes [Annotated]
- Annex K: Language-Defined Attributes [Annotated]
Ada Programming/Attributes/'Compose
edit
Description
editX'Compose(Fraction : X, Exponent : Integer) is an Ada attribute where X is any floating point type.
Floating point types are represented as:
where
- sign is 1 or -1
- mantissa is a fraction in base radix
- radix is the hardware radix (usually 2)
- exponent is an integer
'Compose(Fraction, Exponent) returns the floating point number Fraction with the exponent replaced with Exponent.
Example
editwith Ada.Text_IO; procedure Compose is package T_IO renames Ada.Text_IO; package F_IO is new Ada.Text_IO.Float_IO (Float); X : Float := 1.0; begin T_IO.Put (" X = "); F_IO.Put(Item => X, Exp => 0); T_IO.New_Line; for Exp in -2..2 loop T_IO.Put ("Float'Compose(X, " & Integer'Image(Exp) & ") = "); F_IO.Put(Item => Float'Compose(X, Exp), Exp => 0); T_IO.New_Line; end loop; end Compose;
The output with GNAT 4.6 on the x86-64 architecture is:
X = 1.00000 Float'Compose(X, -2) = 0.12500 Float'Compose(X, -1) = 0.25000 Float'Compose(X, 0) = 0.50000 Float'Compose(X, 1) = 1.00000 Float'Compose(X, 2) = 2.00000
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Constrained
editDescription
editTrue if A of discriminated type denotes a constant, a value, or a constrained variable.
Yields the value True if A denotes a constant, a value, a tagged object, or a constrained variable, and False otherwise.
The value of this attribute is of the predefined type Boolean.
Example
editA’Constrained return Boolean
Ada Programming/Attributes/'Copy Sign
edit
function
S'Copy_Sign (Value, Sign : T)return
T
Description
editS'Copy_Sign(X, Y) is an Ada attribute where S is any floating-point type, and X and Y are any instance of that type. This attribute represents the floating point value with the magnitude of X and the sign of Y.
If the resulting value is outside the base range of S, a Constraint_Error exception is raised.
Example
editX : Float := 1.5; Y : Float := -1.0; Z : Float := 1.0;pragma
Assert (Float'Copy_Sign ( X, Y) = -1.5); -- OKpragma
Assert (Float'Copy_Sign ( X, Z) = 1.5); -- OKpragma
Assert (Float'Copy_Sign (-X, Z) = 1.5); -- OKpragma
Assert (Float'Copy_Sign ( Y, Z) = -1.0); -- Wrong
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Count
edit
Description
editX'Count is an Ada attribute where X is an entry point in a protected type. This attribute returns the number of tasks currently enqueued waiting for entrance into the entry procedure.
Example
editprotected
type
My_Protected_Typeis
entry
My_Entry;procedure
Get_Count( Task_Count :out
Natural );end
My_Protected_Type; ...procedure
body
Get_Count( Task_Count :out
Natural )is
begin
Task_Count := My_Entry'Count;end
Get_Count;
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Default Bit Order
editDescription
editStandard'Default_Bit_Order
(Standard
is the only allowed prefix), provides the value System.Default_Bit_Order
as a Pos
value (0 for High_Order_First
, 1 for Low_Order_First
). This is used to construct the definition of Default_Bit_Order
in package System
.
Ada Programming/Attributes/'Default Scalar Storage Order
editDescription
editStandard'Default_Scalar_Storage_Order
(Standard
is the only allowed prefix), provides the current value of the default scalar storage order (as specified using pragma Default_Scalar_Storage_Order
, or equal to Default_Bit_Order
if unspecified) as a System.Bit_Order
value. This is a static attribute.
Ada Programming/Attributes/'Definite
editDescription
editS'Definite yields True if the actual subtype corresponding to S is definite; otherwise, it yields False.
The value of this attribute is of the predefined type Boolean.
Example
editS’Definite return Boolean
Ada Programming/Attributes/'Delta
edit
Description
editX'Delta is an Ada attribute where X is any fixed point type. This attribute represents the delta specified in the type definition of X.
Example
edittype
My_Fixedis
delta
0.1range
0.0 .. 100.0;pragma
Assert (My_Fixed'Delta = 0.1); -- OK
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Types/delta
- Ada Programming/Attributes/'Digits
Ada Reference Manual
editAda Programming/Attributes/'Denorm
editDescription
editTrue if every value is expressible in canonical form with an an expo-nent of T’Machine_Emin.
Yields the value True if every value expressible in the form
± mantissa · T'Machine_RadixT'Machine_Emin
where mantissa is a nonzero T'Machine_Mantissa-digit fraction in the number base T'Machine_Radix, the first digit of which is zero, is a machine number (see 3.5.7) of the type T; yields the value False otherwise.
The value of this attribute is of the predefined type Boolean.
Example
editS’Denorm return Boolean
Ada Programming/Attributes/'Deref
editDescription
editThe attribute typ'Deref(expr)
where expr
is of type System.Address
yields the variable of type typ
that is located at the given address. It is similar to (totyp (expr).all)
, where totyp
is an unchecked conversion from address to a named access-to- type, except that it yields a variable, so it can be used on the left side of an assignment.
Ada Programming/Attributes/'Descriptor Size
editDescription
edit
Nonstatic attribute Descriptor_Size
returns the size in bits of the descriptor allocated for a type. The result is non-zero only for unconstrained array types and the returned value is of type universal integer. In GNAT, an array descriptor contains bounds information and is located immediately before the first element of the array.
type Unconstr_Array is array (Short_Short_Integer range <>) of Positive;
Put_Line ("Descriptor size = " & Unconstr_Array'Descriptor_Size'Img);
The attribute takes into account any padding due to the alignment of the component type. In the example above, the descriptor contains two values of type Short_Short_Integer
representing the low and high bound. But, since Positive
has an alignment of 4, the size of the descriptor is 2 * Short_Short_Integer'Size
rounded up to the next multiple of 32, which yields a size of 32 bits, i.e. including 16 bits of padding.
Ada Programming/Attributes/'Digits
edit
Description
editX'Digits is an Ada attribute where X is any floating point type or decimal fixed point type. This attribute represents the number of decimal digits in the mantissa of type X.
Example
edittype
My_Floatis
digits
10range
0.0 .. 100.0; ...pragma
Assert (My_Float'Digits = 10); -- OK
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Elab Body
editDescription
editThis attribute can only be applied to a program unit name. It returns the entity for the corresponding elaboration procedure for elaborating the body of the referenced unit. This is used in the main generated elaboration procedure by the binder and is not normally used in any other context. However, there may be specialized situations in which it is useful to be able to call this elaboration procedure from Ada code, e.g., if it is necessary to do selective re-elaboration to fix some error.
Ada Programming/Attributes/'Elab Spec
editThis attribute can only be applied to a program unit name. It returns the entity for the corresponding elaboration procedure for elaborating the spec of the referenced unit. This is used in the main generated elaboration procedure by the binder and is not normally used in any other context. However, there may be specialized situations in which it is useful to be able to call this elaboration procedure from Ada code, e.g., if it is necessary to do selective re-elaboration to fix some error.
Ada Programming/Attributes/'Elab Subp Body
editDescription
editThis attribute can only be applied to a library level subprogram name and is only allowed in CodePeer mode. It returns the entity for the corresponding elaboration procedure for elaborating the body of the referenced subprogram unit. This is used in the main generated elaboration procedure by the binder in CodePeer mode only and is unrecognized otherwise.
Ada Programming/Attributes/'Elaborated
editDescription
editThe prefix of the 'Elaborated
attribute must be a unit name. The value is a Boolean which indicates whether or not the given unit has been elaborated. This attribute is primarily intended for internal use by the generated code for dynamic elaboration checking, but it can also be used in user programs. The value will always be True once elaboration of all units has been completed. An exception is for units which need no elaboration, the value is always False for such units.
Ada Programming/Attributes/'Emax
editDescription
editThe Emax
attribute is provided for compatibility with Ada 83. See the Ada 83 reference manual for an exact description of the semantics of this attribute.
Ada Programming/Attributes/'Enabled
editDescription
editThe Enabled
attribute allows an application program to check at compile time to see if the designated check is currently enabled. The prefix is a simple identifier, referencing any predefined check name (other than All_Checks
) or a check name introduced by pragma Check_Name. If no argument is given for the attribute, the check is for the general state of the check, if an argument is given, then it is an entity name, and the check indicates whether an Suppress
or Unsuppress
has been given naming the entity (if not, then the argument is ignored).
Note that instantiations inherit the check status at the point of the instantiation, so a useful idiom is to have a library package that introduces a check name with pragma Check_Name
, and then contains generic packages or subprograms which use the Enabled
attribute to see if the check is enabled. A user of this package can then issue a pragma Suppress
or pragma Unsuppress
before instantiating the package or subprogram, controlling whether the check will be present.
Ada Programming/Attributes/'Enum Rep
edit
Description
editThis language feature has been introduced in Ada 2022.
User_Enum_Type'Enum_Rep(Instance);
where User_Enum_Type
is an enumeration type and Instance
is an instance of that type will return the underlying representation for that instance of the enumeration. The default representation of an enumeration is based on its position (starting at zero). However, Ada does provide language facilities for specifying the representation independently of the position. The Enum_Rep allows you to retrieve that representation. Generally in Ada, enumerations are their own type and the representation is not important. However, in the interests of cross language compatibility and for possible use in embedded programming the representation can be manipulated. While the core language allows you to change the representation, it doesn't provide a convenient attribute for retrieving it. This extended attribute addresses that need. Using it does require that you know the underlying type used to support the enumeration, since Enum_Rep
returns that type. Typically, the standard type Integer is sufficient.
Note that this attribute is now standard in Ada 2022. In earlier Ada versions, it is available in GNAT as an implementation defined attribute, but the standard and portable way to get the internal representation was using an instantiation of Unchecked_Conversion.
Example
edittype
Enum_Typeis
(Enum1, Enum2, Enum3); Enum_Val : Enum_Type := Enum1;
pragma
Assert (Enum_Type'Enum_Rep(Enum_Val) = 0); -- OK
See also
editWikibook
editAda Reference Manual
edit- 13.4: Enumeration Representation Clauses [Annotated]
- Annex K: Language-Defined Attributes [Annotated]
Ada 2022 Overview
editExternal links
editGNAT Reference Manual > Implementation Defined Attributes > Enum_Rep
Ada Programming/Attributes/'Enum Val
editThis language feature has been introduced in Ada 2022.
Description
editReturn the enumeration literal represented by a given number.
For every enumeration subtype S
, S'Enum_Val
denotes a function with the following spec:
function S'Enum_Val (Arg : <Universal_Integer>) return S'Base;
The function returns the enumeration value whose representation matches the argument, or raises Constraint_Error if no enumeration literal of the type has the matching value. This will be equal to the value of the Val
attribute in the absence of an enumeration representation clause. This is a static attribute (i.e., the result is static if the argument is static).
Example
edittype
Enum_Typeis
(Enum1, Enum2, Enum3);
pragma
Assert (Enum_Type'Enum_Val(0) = Enum1); -- OK
See also
editWikibook
editAda Reference Manual
edit- 13.4: Enumeration Representation Clauses [Annotated]
- Annex K: Language-Defined Attributes [Annotated]
Ada 2022 Overview
editExternal links
editGNAT Reference Manual > Implementation Defined Attributes > Enum_Val
Ada Programming/Attributes/'Epsilon
editDescription
editThe Epsilon
attribute is provided for compatibility with Ada 83. See the Ada 83 reference manual for an exact description of the semantics of this attribute.
Ada Programming/Attributes/'Exponent
editDescription
editReturns normalized exponent of the floating point argument.
For every subtype S of a floating point type T:
S'Exponent denotes a function with the following specification:
function S'Exponent (X : T) return universal_integer
The function yields the normalized exponent of X.
Example
editS’Exponent (X:T) return universal_integer
Ada Programming/Attributes/'Extended Aft
editDescription
editReturns the minimum number of characters required for the fractional part of the representation of the fixed point subtype T. All parameters are optional. They are:
- Base : Number_Base := 10
- the base in which the digits will be represented.
- Based : Boolean := FALSE
- if TRUE, compute the width of the based format (e.g.,10#99.0#).
Example
editT'EXTENDED_AFT(Base, Based)
Ada Programming/Attributes/'Extended Base
editDescription
editFor a type T returns the base type of T. This attribute is allowed only as the prefix of the name of another attribute. (This is the old Ada83 'BASE attribute.)
Example
editT'EXTENDED_BASE
Ada Programming/Attributes/'Extended Base
editDescription
editFor a type T returns the base type of T. This attribute is allowed only as the prefix of the name of another attribute. (This is the old Ada83 'BASE attribute.)
Example
editT'EXTENDED_BASE
Ada Programming/Attributes/'Extended Digits
editDescription
editReturns the number of digits using Base in the mantissa of model numbers in the floating point subtype T. The optional parameter is:
- Base : Number_Base := 10
- the base that the subtype is defined in
Example
editT'EXTENDED_DIGITS(Base)
Ada Programming/Attributes/'Extended Fore
editDescription
editReturns the minimum number of characters required for the integer part of the representation of the fixed point subtype T. All parameters are optional. They are:
- Base : Number_Base := 10
- the base in which the digits will be represented.
- Based : Boolean := FALSE
- if TRUE, compute the width of the based format (e.g., 10#99.0#).
Example
editT'EXTENDED_FORE(Base, Based)
Ada Programming/Attributes/'Extended Image
editDescription
editReturns the image of type STRING associated with a specified item as defined for the PUT procedure in TEXT_IO generic package appropriate for type T (e.g., TEXT_IO.INTEGER_IO(T) if T is an integer type). T may denote an integer, enumeration, floating point or fixed point type name. Named parameter notation may not be used. The parameters are:
- Item : T
- the item for which you want the image. Required.
- Width : Field := 0
- the minimum number of characters to be in the string that is returned.
- Base : Number_Base := 10
- the base in which the image is to be displayed.
- Based : Boolean := FALSE
- if TRUE, return the string in based format (e.g., 10#99#).
- Space_If_Positive : Boolean := FALSE
- if TRUE, a positive integer will be preceded by a blank in the string returned.
Example
editT'EXTENDED_IMAGE(Item, Width, Base, Based, Space_If_Positive)
Ada Programming/Attributes/'Extended Value
editDescription
editReturns the value of type T associated with Item as defined for the GET procedure in the TEXT_IO generic package appropriate for type T (e.g., TEXT_IO.INTEGER_IO(T) if T is an integer type). T may denote an integer, enumeration, floating point, or fixed point type.
- Item
- is the STRING for which you want the value.
Example
editT'EXTENDED_VALUE(Item)
Ada Programming/Attributes/'Extended Wide Image
editDescription
editReturns the image of type WIDE_STRING associated with a specified item as defined for the PUT procedure in TEXT_IO generic package appropriate for type T (e.g., TEXT_IO.INTEGER_IO(T) if T is an integer type). T may denote an integer, enumeration, floating point or fixed point type name. Named parameter notation may not be used. The parameters are:
- Item : T
- the item for which you want the image. Required.
- Width : Field := 0
- the minimum number of characters to be in the string that is returned.
- Base : Number_Base := 10
- the base in which the image is to be displayed.
- Based : Boolean := FALSE
- if TRUE, return the string in based format (e.g., 10#99#).
- Space_If_Positive : Boolean := FALSE
- if TRUE, a positive integer will be preceded by a blank in the string returned.
Example
editT'EXTENDED_WIDE_IMAGE(Item, Width, Base, Based, Space_If_Positive)
Ada Programming/Attributes/'Extended Wide Value
editDescription
editReturns the value of type T associated with Item as defined for the GET procedure in the TEXT_IO generic package appropriate for type T (e.g., TEXT_IO.INTEGER_IO(T) if T is an integer type). T may denote an integer, enumeration, floating point, or fixed point type.
- Item
- is the WIDE_STRING for which you want the value.
Example
editT'EXTENDED_WIDE_VALUE(Item)
Ada Programming/Attributes/'Extended Wide Width
editDescription
editReturns the width for (sub)type T. T may be integer or enumeration type. All the parameters are optional. They are:
- Base : Number_Base := 10
- the base for which the width will be calculated.
- Based : Boolean := FALSE
- if TRUE, compute the width of the based format (e.g., 10#99#).
- Space_If_Positive : BOOLEAN := FALSE
- if TRUE, compute the width assuming that a positive integer will be preceded by a blank.
Example
editT'EXTENDED_WIDE_WIDTH(Base, Based, Space_If_Positive)
Ada Programming/Attributes/'Extended Width
editDescription
editReturns the width for (sub)type T. T may be integer or enumeration type. All the parameters are optional. They are:
- Base : Number_Base := 10
- the base for which the width will be calculated.
- Based : Boolean := FALSE
- if TRUE, compute the width of the based format (e.g., 10#99#).
- Space_If_Positive : BOOLEAN := FALSE
- if TRUE, compute the width assuming that a positive integer will be preceded by a blank.
Example
editT'EXTENDED_WIDTH(Base, Based, Space_If_Positive)
Ada Programming/Attributes/'External Tag
editDescription
editAn external string representation of the tagged type.
For every subtype S of a tagged type T (specific or class-wide):
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.
Example
editS’External_Tag return String
Ada Programming/Attributes/'Fast Math
editDescription
editStandard'Fast_Math
(Standard
is the only allowed prefix) yields a static Boolean value that is True if pragma Fast_Math
is active, and False otherwise.
Ada Programming/Attributes/'Finalization Size
editDescription
editThe prefix of attribute Finalization_Size
must be an object or a non-class-wide type. This attribute returns the size of any hidden data reserved by the compiler to handle finalization-related actions. The type of the attribute is universal_integer.
Finalization_Size
yields a value of zero for a type with no controlled parts, an object whose type has no controlled parts, or an object of a class-wide type whose tag denotes a type with no controlled parts.
Note that only heap-allocated objects contain finalization data.
Ada Programming/Attributes/'First
edit
Description
editX'First
, where X
is any scalar subtype (for example integer, enumerated, real), is an attribute that represents the first value (lower bound) in the range of X
.
A'First
, where A
is an array, denotes the first index value. For more-dimensional arrays, A'First(N)
denotes the first index value of the Nth dimension (N must be static).
Example
edittype
My_Enumis
(Enum1, Enum2, Enum3);type
My_Intis
range
-1 .. 5; ...pragma
Assert (My_Enum'First = Enum1); -- OKpragma
Assert (My_Int'First = -1); -- OKpragma
Assert (My_Int'First = 0); -- Wrong!
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Fixed Value
editDescription
edit
For every fixed-point type S
, S'Fixed_Value
denotes a function with the following specification:
function S'Fixed_Value (Arg : <Universal_Integer>) return S;
The value returned is the fixed-point value V
such that:
V = Arg * S'Small
The effect is thus similar to first converting the argument to the integer type used to represent S
, and then doing an unchecked conversion to the fixed-point type. The difference is that there are full range checks, to ensure that the result is in range. This attribute is primarily intended for use in implementation of the input-output functions for fixed-point values.
Ada Programming/Attributes/'Floor
edit
Description
editX'Floor(Y) is an Ada attribute where X is any floating-point type and Y is any instance of that type. This attribute represents the largest integer value that is less than or equal to Y.
Example
editX : Float := 1.5; Y : Float := 1.0; Z : Float := 1.999;pragma
Assert (Float'Floor (X) = 1.0); -- OKpragma
Assert (Float'Floor (Y) = 1.0); -- OKpragma
Assert (Float'Floor (Z) = 2.0); -- Wrong
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Attributes/'Ceiling
- Ada Programming/Attributes/'Rounding
Ada Reference Manual
editAda Programming/Attributes/'Fore
editDescription
editMinimum number of characters needed before the decimal point.
S'Fore yields the minimum number of characters needed before the decimal point for the decimal representation of any value of the subtype S, assuming that the representation does not include an exponent, but includes a one-character prefix that is either a minus sign or a space. (
This minimum number does not include superfluous zeros or underlines, and is at least 2.)
The value of this attribute is of the type universal_integer.
Example
editS’Fore return universal_integer
Ada Programming/Attributes/'Fraction
edit
Description
editX'Fraction(Y) is an Ada attribute where X is any floating-point type and Y is any instance of that type.
X'Fraction(Y) returns the floating point number Y with the exponent replaced with 0. This is the same as X'Compose(Y, 0).
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'From Any
editDescription
editThis internal attribute is used for the generation of remote subprogram stubs in the context of the Distributed Systems Annex.
Ada Programming/Attributes/'Has Access Values
editDescription
editThe prefix of the Has_Access_Values
attribute is a type. The result is a Boolean value which is True if the is an access type, or is a composite type with a component (at any nesting depth) that is an access type, and is False otherwise. The intended use of this attribute is in conjunction with generic definitions. If the attribute is applied to a generic private type, it indicates whether or not the corresponding actual type has access values.
Ada Programming/Attributes/'Has Discriminants
editDescription
editThe prefix of the Has_Discriminants
attribute is a type. The result is a Boolean value which is True if the type has discriminants, and False otherwise. The intended use of this attribute is in conjunction with generic definitions. If the attribute is applied to a generic private type, it indicates whether or not the corresponding actual type has discriminants.
Ada Programming/Attributes/'Has Same Storage
editDescription
editReturns True if the representation of X2 occupies exactly the same bits as the representation of X and the objects occupy at least one bit.
For a prefix X that denotes an object:
X'Has_Same_Storage denotes a function with the following specification:
function X'Has_Same_Storage (Arg : any_type) return Boolean
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.
Example
editX’Has_Same_Storage (X2:any_type) return Boolean
Ada Programming/Attributes/'Has Tagged Values
editDescription
editThe prefix of the Has_Tagged_Values
attribute is a type. The result is a Boolean value which is True if the type is a composite type (array or record) that is either a tagged type or has a subcomponent that is tagged, and is False otherwise. The intended use of this attribute is in conjunction with generic definitions. If the attribute is applied to a generic private type, it indicates whether or not the corresponding actual type has access values.
Ada Programming/Attributes/'Identity
edit
Description
editX'Identity is an Ada attribute where X is any task. This attribute returns a unique identifying string (of type "Task_ID"). This string is used in some Ada tasking libraries for task identification. It may also be used directly by the user for output purposes, to determine if two tasks are the same task, etc.
Example
edittask
My_Task;task
My_Other_Task; ...if
My_Task'Identity = My_Other_Task'Identitythen
-- Do somethingend
if
;
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Image
edit
Description
editX'Image(Y) is an Ada attribute where X is any discrete type and Y is an instance of that type. This attribute returns a string representation of the value passed as input.
This attribute is a useful way to automatically convert from a type value to a string suitable for output.
In Ada 2022 a simplified version was added:
Y’Image return String
Image of the value of Y as a String.
Example
edittype My_Enum is (Enum1, Enum2, Enum3);
...
pragma Assert (My_Enum'Image (Enum1) = "ENUM1");
pragma Assert (Enum1'Image = "ENUM1"); -- Ada 2022
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Img
editDescription
editThe Img
attribute differs from Image
in that, while both can be applied directly to an object, Img
cannot be applied to types.
Example usage of the attribute:
Put_Line ("X = " & X'Img);
which has the same meaning as the more verbose:
Put_Line ("X = " & T'Image (X));
where T
is the (sub)type of the object X
.
Note that technically, in analogy to Image
, X'Img
returns a parameterless function that returns the appropriate string when called. This means that X'Img
can be renamed as a function-returning-string, or used in an instantiation as a function parameter.
Ada Programming/Attributes/'Index
editDescription
editWithin a precondition or postcondition expression for entry family E, denotes the value of the entry index for the call of E.
Example
editE’Index return entry_index_subtype
Ada Programming/Attributes/'Initialized
editDescription
editFor the syntax and semantics of this attribute, see the SPARK 2014 Reference Manual, section 6.10.
Ada Programming/Attributes/'Input
editDescription
editReads and returns one value from the Stream argument.
For every subtype S of a specific type T:
S'Input denotes a function with the following specification:
function S'Input (Stream : not null access Ada.Streams.Root_Stream_Type'Class) return T
S'Input reads and returns one value from Stream, using any bounds or discriminants written by a corresponding S'Output to determine how much to read.
Example
editS’Input (Stream:access Ada.Streams.Root_Stream_Type’Class) return T
Ada Programming/Attributes/'Integer Value
editDescription
edit
For every integer type S
, S'Integer_Value
denotes a function with the following spec:
function S'Integer_Value (Arg : <Universal_Fixed>) return S;
The value returned is the integer value V
, such that:
Arg = V * T'Small
where T
is the type of Arg
. The effect is thus similar to first doing an unchecked conversion from the fixed-point type to its corresponding implementation type, and then converting the result to the target integer type. The difference is that there are full range checks, to ensure that the result is in range. This attribute is primarily intended for use in implementation of the standard input-output functions for fixed-point values.
Ada Programming/Attributes/'Invalid Value
editDescription
editFor every scalar type S, S’Invalid_Value returns an undefined value of the type. If possible this value is an invalid representation for the type. The value returned is identical to the value used to initialize an otherwise uninitialized value of the type if pragma Initialize_Scalars is used, including the ability to modify the value with the binder -Sxx flag and relevant environment variables at run time.
Ada Programming/Attributes/'Large
editThe Large
attribute is provided for compatibility with Ada 83. See the Ada 83 reference manual for an exact description of the semantics of this attribute.
Ada Programming/Attributes/'Last
edit
Description
editX'Last
, where X
is any scalar subtype (for example integer, enumerated, real), is an attribute that represents the last value (upper bound) in the range of X
.
A'Last
, where A
is an array, denotes the last index value. For more-dimensional arrays, A'Last(N)
denotes the last index value of the Nth dimension (N must be static).
Example
edittype
My_Enumis
(Enum1, Enum2, Enum3);type
My_Intis
range
-1 .. 5; ...pragma
Assert (My_Enum'Last = Enum3); -- OKpragma
Assert (My_Int'Last = 5); -- OKpragma
Assert (My_Int'Last = 4); -- Wrong!
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Attributes/'First
- Ada Programming/Attributes/'Range
Ada Reference Manual
editAda Programming/Attributes/'Leading Part
editDescription
editThe leading part of floating point value with number of radix digits given by second argument.
Example
editS’Leading_Part (X:T;Radix_Digits:universal_integer) return T
Ada Programming/Attributes/'Length
edit
Description
edit'Length is an array type attribute. It may be used with or without an input parameter.
Without an input parameter, 'Length is an integer that represents the length of the first dimension of the array type.
With an input parameter, 'Length(N) is an integer that represents the length of the Nth dimension of the array type. N must be a positive number within the dimensions of the array.
Example
editIf you declare:
type
My_Vectoris
array
(1 .. 7)of
Integer;type
My_Matrixis
array
(1 .. 5, 1 .. 10)of
Integer;
then
pragma
Assert (My_Vector'Length = 7);pragma
Assert (My_Matrix'Length(1) = 5);pragma
Assert (My_Matrix'Length(2) = 10);pragma
Assert (My_Vector'Length(1) = My_Vector'Length);pragma
Assert (My_Matrix'Length(1) = My_Matrix'Length);
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Library Level
editDescription
editP'Library_Level
, where P is an entity name, returns a Boolean value which is True if the entity is declared at the library level, and False otherwise. Note that within a generic instantiation, the name of the generic unit denotes the instance, which means that this attribute can be used to test if a generic is instantiated at the library level, as shown in this example:
generic
...
package Gen is
pragma Compile_Time_Error
(not Gen'Library_Level,
"Gen can only be instantiated at library level");
...
end Gen;
Ada Programming/Attributes/'Loop Entry
editDescription
editX'Loop_Entry [(loop_name)]
The Loop_Entry
attribute is used to refer to the value that an expression had upon entry to a given loop in much the same way that the Old
attribute in a subprogram postcondition can be used to refer to the value an expression had upon entry to the subprogram. The relevant loop is either identified by the given loop name, or it is the innermost enclosing loop when no loop name is given.
A Loop_Entry
attribute can only occur within an Assert
, Assert_And_Cut
, Assume
, Loop_Variant
or Loop_Invariant
pragma. In addition, such a pragma must be one of the items in the sequence of statements of a loop body, or nested inside block statements that appear in the sequence of statements of a loop body. A common use of Loop_Entry
is to compare the current value of objects with their initial value at loop entry, in a Loop_Invariant
pragma.
The effect of using X'Loop_Entry
is the same as declaring a constant initialized with the initial value of X
at loop entry. This copy is not performed if the loop is not entered, or if the corresponding pragmas are ignored or disabled.
Ada Programming/Attributes/'Machine
editDescription
editMachine representation of floating point argument.
If X is a machine number of the type T, the function yields X; otherwise, it yields the value obtained by rounding or truncating X to either one of the adjacent machine numbers of the type T.
Constraint_Error is raised if rounding or truncating X to the precision of the machine numbers results in a value outside the base range of S.
A zero result has the sign of X when S'Signed_Zeros is True.
Example
editS’Machine (X:T) return T
Ada Programming/Attributes/'Machine Emax
edit
Description
editX'Machine_Emax is an Ada attribute where X is any floating point type.
Floating point types are represented as:
where
- sign is 1 or -1
- mantissa is a fraction in base radix
- radix is the hardware radix (usually 2)
- exponent is an integer
'Machine_Emax returns the largest exponent.
Example
editwith
Ada.Text_IO;procedure
Machine_Emaxis
package
T_IOrenames
Ada.Text_IO;package
I_IOis
new
Ada.Text_IO.Integer_IO (Integer);begin
T_IO.Put ("Emax of Float type = "); I_IO.Put (Float'Machine_Emax); T_IO.New_Line; T_IO.Put ("Emax of Long_Float type = "); I_IO.Put (Long_Float'Machine_Emax); T_IO.New_Line;end
Machine_Emax;
The output with GNAT 4.6 on the x86-64 architecture is:
Emax of Float type = 128 Emax of Long_Float type = 1024
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Attributes/'Machine_Emin
- Ada Programming/Attributes/'Machine_Mantissa
- Ada Programming/Attributes/'Machine_Radix
Ada Reference Manual
editAda Programming/Attributes/'Machine Emin
edit
Description
editX'Machine_Emin is an Ada attribute where X is any floating point type.
Floating point types are represented as:
where
- sign is 1 or -1
- mantissa is a fraction in base radix
- radix is the hardware radix (usually 2)
- exponent is an integer
'Machine_Emin returns the smallest exponent.
Example
editwith
Ada.Text_IO;procedure
Machine_Eminis
package
T_IOrenames
Ada.Text_IO;package
I_IOis
new
Ada.Text_IO.Integer_IO (Integer);begin
T_IO.Put ("Emin of Float type = "); I_IO.Put (Float'Machine_Emin); T_IO.New_Line; T_IO.Put ("Emin of Long_Float type = "); I_IO.Put (Long_Float'Machine_Emin); T_IO.New_Line;end
Machine_Emin;
The output with GNAT 4.6 on the x86-64 architecture is:
Emin of Float type = -125 Emin of Long_Float type = -1021
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Attributes/'Machine_Emax
- Ada Programming/Attributes/'Machine_Mantissa
- Ada Programming/Attributes/'Machine_Radix
Ada Reference Manual
editAda Programming/Attributes/'Machine Mantissa
edit
Description
editX'Machine_Mantissa is an Ada attribute where X is any floating point type.
Floating point types are represented as:
where
- sign is 1 or -1
- mantissa is a fraction in base radix
- radix is the hardware radix (usually 2)
- exponent is an integer
'Machine_Mantissa returns the maximum number of digits in the mantissa.
Example
editwith
Ada.Text_IO;procedure
Machine_Mantissais
package
T_IOrenames
Ada.Text_IO;package
I_IOis
new
Ada.Text_IO.Integer_IO (Integer);begin
T_IO.Put ("Mantissa of Float type = "); I_IO.Put (Float'Machine_Mantissa); T_IO.New_Line; T_IO.Put ("Mantissa of Long_Float type = "); I_IO.Put (Long_Float'Machine_Mantissa); T_IO.New_Line;end
Machine_Mantissa;
The output with GNAT 4.6 on the x86-64 architecture is:
Mantissa of Float type = 24 Mantissa of Long_Float type = 53
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Attributes/'Machine_Emax
- Ada Programming/Attributes/'Machine_Emin
- Ada Programming/Attributes/'Machine_Radix
Ada Reference Manual
editAda Programming/Attributes/'Machine Overflows
editDescription
editTrue if numeric overflow detected for fixed or floating point.
Yields the value True if overflow and divide-by-zero are detected and reported by raising Constraint_Error for every predefined operation that yields a result of the type T; yields the value False otherwise.
The value of this attribute is of the predefined type Boolean.
Example
editS’Machine_Overflows return Boolean
Ada Programming/Attributes/'Machine Radix
edit
Description
editX'Machine_Radix is an Ada attribute where X is any floating or fixed point type. It returns the radix of the hardware representation of type X. On most machines this will be 2.
Machine_Radix is also an Ada aspect that may be set for decimal fixed point types via an attribute definition clause. The value is constrained to either 2 or 10.
Example
editwith
Ada.Text_IO;procedure
Machine_Radixis
package
T_IOrenames
Ada.Text_IO;package
I_IOis
new
Ada.Text_IO.Integer_IO (Integer);type
My_Fixed_Point_Typeis
delta
0.1range
-1.0 .. 1.0;type
My_Decimal_Typeis
delta
0.01digits
10;begin
T_IO.Put ("Radix of Float type = "); I_IO.Put (Float'Machine_Radix); T_IO.New_Line; T_IO.Put ("Radix of My_Fixed_Point_Type = "); I_IO.Put (My_Fixed_Point_Type'Machine_Radix); T_IO.New_Line; T_IO.Put ("Radix of My_Decimal_Type type = "); I_IO.Put (My_Decimal_Type'Machine_Radix); T_IO.New_Line;end
Machine_Radix;
The output with GNAT 4.6 on the x86-64 architecture is:
Radix of Float type = 2 Radix of My_Fixed_Point_Type = 2 Radix of My_Decimal_Type type = 2
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Attributes/'Machine_Emax
- Ada Programming/Attributes/'Machine_Emin
- Ada Programming/Attributes/'Machine_Mantissa
Ada Reference Manual
editAda Programming/Attributes/'Machine Rounding
editDescription
editYields the integral value nearest to X.
The function yields the integral value nearest to X.
If X lies exactly halfway between two integers, one of those integers is returned, but which of them is returned is unspecified.
A zero result has the sign of X when S'Signed_Zeros is True.
This function provides access to the rounding behavior which is most efficient on the target processor.
Example
editS’Machine_Rounding (X:T) return T
Ada Programming/Attributes/'Machine Rounds
editDescription
editTrue if rounding is performed on inexact results of the fixed or floating point.
Yields the value True if rounding is performed on inexact results of every predefined operation that yields a result of the type T; yields the value False otherwise.
The value of this attribute is of the predefined type Boolean.
Example
editS’Machine_Rounds return Boolean
Ada Programming/Attributes/'Machine Size
editDescription
editThis attribute is identical to the Object_Size
attribute. It is provided for compatibility with the DEC Ada 83 attribute of this name.
Ada Programming/Attributes/'Mantissa
editDescription
editThe Mantissa
attribute is provided for compatibility with Ada 83. See the Ada 83 reference manual for an exact description of the semantics of this attribute.
Ada Programming/Attributes/'Max
edit
Description
edit'Max(X, Y) is a scalar type attribute. It returns the greater of the two parameters.
Example
edittype My_Enum is (Enum1, Enum2, Enum3); A : Integer := 3; B : Integer := -5; X : Float := 1.0; Y : Float := 1.5; ... pragma Assert (My_Enum'Max(Enum3, Enum1) = Enum3); pragma Assert (Integer'Max(A, B) = 3); pragma Assert (Float'Max(X, Y) = 1.5);
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Max Alignment For Allocation
editDescription
editMaximum value for Alignment that can be requested by the implementation via Allocate for an access type whose designated subtype is S.
Denotes the maximum value for Alignment that can be requested by the implementation via Allocate for an access type whose designated subtype is S.
The value of this attribute is of type universal_integer.
Example
editS’Max_Alignment_For_Allocation return universal_integer
Ada Programming/Attributes/'Max Integer Size
editDescription
editStandard'Max_Integer_Size
(Standard
is the only allowed prefix) provides the size of the largest supported integer type for the target. The result is a static constant.
Ada Programming/Attributes/'Max Size In Storage Elements
editDescription
editMaximum value for Size_In_Storage_Elements that will be requested via Allocate.
Denotes the maximum value for Size_In_Storage_Elements that can be requested by the implementation via Allocate for an access type whose designated subtype is S. The value of this attribute is of type universal_integer.
Example
editS’Max_Size_In_Storage_Elements return universal_integer
Ada Programming/Attributes/'Maximum Alignment
editDescription
editStandard'Maximum_Alignment
(Standard
is the only allowed prefix) provides the maximum useful alignment value for the target. This is a static value that can be used to specify the alignment for an object, guaranteeing that it is properly aligned in all cases.
Ada Programming/Attributes/'Mechanism Code
editDescription
editfunc'Mechanism_Code
yields an integer code for the mechanism used for the result of function func
, and subprog'Mechanism_Code (n)
yields the mechanism used for formal parameter number n (a static integer value, with 1 meaning the first parameter) of subprogram subprog
. The code returned is:
- 1
- by copy (value)
- 2
- by reference
Ada Programming/Attributes/'Min
edit
Description
edit'Min(X, Y) is a scalar type attribute. It returns the lesser of the two parameters.
Example
edittype My_Enum is (Enum1, Enum2, Enum3);
A : Integer := 3;
B : Integer := -5;
X : Float := 1.0;
Y : Float := 1.5;
-- ...
pragma Assert (My_Enum'Min(Enum3, Enum1) = Enum1);
pragma Assert (Integer'Min(A, B) = -5);
pragma Assert (Float'Min(X, Y) = 1.0);
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Mod
editDescription
editWill correctly convert any integer type to a given modular type (S), using wraparound semantics.
This function returns Arg mod S'Modulus, as a value of the type of S.
Example
editS’Mod (X:T) return S
Ada Programming/Attributes/'Model
editDescription
editModel number of floating point type.
If the Numerics Annex is not supported, the meaning of this attribute is implementation defined.
Example
editS’Model (X:T) return T
Ada Programming/Attributes/'Model Emin
editDescription
editModel number version of S”Machine_Emin.
Yields the smallest (most negative) value of exponent such that every value expressible in the canonical form (for the type T), having a mantissa of T'Machine_Mantissa digits, is a machine number (see 3.5.7) of the type T.
This attribute yields a value of the type universal_integer.
Example
editS’Model_Emin return universal_integer
Ada Programming/Attributes/'Model Epsilon
editDescription
editAbsolute difference between the model number 1.0 and the next model number above for subtype.
Yields the value T'Machine_Radix1 – T'Model_Mantissa. The value of this attribute is of the type universal_real.
Example
editS’Model_Epsilon return universal_real
Ada Programming/Attributes/'Model Mantissa
editDescription
editModel number version of S’Machine_Mantissa.
Yields the largest value of p such that every value expressible in the canonical form (for the type T), having a p-digit mantissa and an exponent between T'Machine_Emin and T'Machine_Emax, is a machine number of the type T. This attribute yields a value of the type universal_integer.
Example
editS’Model_Mantissa return universal_integer
Ada Programming/Attributes/'Model Small
editDescription
editSmallest positive model number of subtype.
Yields the value T'Machine_RadixT'Model_Emin – 1. The value of this attribute is of the type universal_real.
Example
editS’Model_Small return universal_real
Ada Programming/Attributes/'Modulus
edit
Description
editX'Modulus is an Ada attribute where X is any modular type. This returns the modulus of X.
Example
edittype Unsigned_Byte is mod 2**8; type Unsigned_Word is mod 2**16;pragma
Assert (Unsigned_Byte'Modulus = 256); -- Okpragma
Assert (Unsigned_Word'Modulus = 65536); -- Ok
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Null Parameter
editDescription
editA reference T'Null_Parameter
denotes an imaginary object of type or subtype T
allocated at machine address zero. The attribute is allowed only as the default expression of a formal parameter, or as an actual expression of a subprogram call. In either case, the subprogram must be imported.
The identity of the object is represented by the address zero in the argument list, independent of the passing mechanism (explicit or default).
This capability is needed to specify that a zero address should be passed for a record or other composite object passed by reference. There is no way of indicating this without the Null_Parameter
attribute.
Ada Programming/Attributes/'Object Size
editDescription
edit
The size of an object is not necessarily the same as the size of the type of an object. This is because by default object sizes are increased to be a multiple of the alignment of the object. For example, Natural'Size
is 31, but by default objects of type Natural
will have a size of 32 bits. Similarly, a record containing an integer and a character:
type Rec is record
I : Integer;
C : Character;
end record;
will have a size of 40 (that is Rec'Size
will be 40). The alignment will be 4, because of the integer field, and so the default size of record objects for this type will be 64 (8 bytes).
If the alignment of the above record is specified to be 1, then the object size will be 40 (5 bytes). This is true by default, and also an object size of 40 can be explicitly specified in this case.
A consequence of this capability is that different object sizes can be given to subtypes that would otherwise be considered in Ada to be statically matching. But it makes no sense to consider such subtypes as statically matching. Consequently, GNAT adds a rule to the static matching rules that requires object sizes to match. Consider this example:
procedure BadAVConvert is
2. type R is new Integer;
3. subtype R1 is R range 1 .. 10;
4. subtype R2 is R range 1 .. 10;
5. for R1'Object_Size use 8;
6. for R2'Object_Size use 16;
7. type R1P is access all R1;
8. type R2P is access all R2;
9. R1PV : R1P := new R1'(4);
10. R2PV : R2P;
11. begin
12. R2PV := R2P (R1PV);
|
>>> target designated subtype not compatible with
type "R1" defined at line 3
13. end;
In the absence of lines 5 and 6, types R1
and R2
statically match and hence the conversion on line 12 is legal. But since lines 5 and 6 cause the object sizes to differ, GNAT considers that types R1
and R2
are not statically matching, and line 12 generates the diagnostic shown above.
Similar additional checks are performed in other contexts requiring statically matching subtypes.
Ada Programming/Attributes/'Old
editDescription
editThe value of X on entry, has same type as X.
Each X'Old in a postcondition expression that is enabled, other than those that occur in subexpressions that are determined to be unevaluated, denotes a constant that is implicitly declared at the beginning of the subprogram body, entry body, or accept statement.
Example
editX’Old return T
Ada Programming/Attributes/'Output
editDescription
editWrites the value of X to Stream, including any bounds or discriminants.
Example
editS’Output (Stream:access Ada.Streams.Root_Stream_Type’Class;X)
Ada Programming/Attributes/'Overlaps Storage
editDescription
editReturns True if the representation of X2 shares at least one bit with the representation of the object denoted by X.
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.
Example
editX’Overlaps_Storage (X2) return Boolean
Ada Programming/Attributes/'Parallel Reduce
editDescription
editReduction expression that yields a result equivalent to replacing the attribute identifier with Reduce and the prefix of the attribute with the value_sequence.
X'Parallel_Reduce is a reduction expression that yields a result equivalent to replacing the attribute identifier with Reduce and the prefix of the attribute with the value_sequence:
[parallel for Item of X => Item]
Example
editX’Parallel_Reduce (Reducer,Initial_Value)
Ada Programming/Attributes/'Partition ID
editDescription
editIdentifies the partition in which D was elaborated.
Denotes a value of the type universal_integer that identifies the partition in which D was elaborated. If D denotes the declaration of a remote call interface library unit the given partition is the one where the body of D was elaborated.
Example
editD’Partition_ID return universal_integer
Ada Programming/Attributes/'Passed By Reference
editDescription
edittyp'Passed_By_Reference
for any subtype returns a value of type Boolean
value that is True
if the type is normally passed by reference and False
if the type is normally passed by copy in calls. For scalar types, the result is always False
and is static. For non-scalar types, the result is nonstatic.
Ada Programming/Attributes/'Pool Address
editDescription
editX'Pool_Address
for any object X
returns the address of X within its storage pool. This is the same as X'Address
, except that for an unconstrained array whose bounds are allocated just before the first component, X'Pool_Address
returns the address of those bounds, whereas X'Address
returns the address of the first component.
Here, we are interpreting ‘storage pool’ broadly to mean wherever the object is allocated
, which could be a user-defined storage pool, the global heap, on the stack, or in a static memory area. For an object created by new
, Ptr.all'Pool_Address
is what is passed to Allocate
and returned from Deallocate
.
Ada Programming/Attributes/'Pos
edit
Description
editThe 'Pos attribute is defined for all discrete types. It is a function returning the argument's position number as a universal_integer; the prefix S must be a subtype name. (Universal integers are implicitly converted to any specific integer type as required by the context.)
function
S'Pos (Arg: S'Base)return
universal_integer;
For enumeration types, position numbers start at 0; if the argument does not denote a valid value (perhaps because of an uninitialized variable), the exception Program_Error is raised. For integer types, the attribute returns the value converted to universal_integer. Note that it is not necessary for the actual argument to belong to the subtype S.
Note that representation clauses do not affect position numbering. Whatever underlying value the enumerated value has, the position number will remain the same.
Example
editI: Integer := -30;pragma
Assert (Integer'Pos(I) = -30); -- of type universal_integertype
My_Enumis
(Enum1, Enum2, Enum3);for
My_Enumuse
(Enum1 => 2, Enum2 => 4, Enum3 => 6); ...pragma
Assert (My_Enum'Pos(Enum1) = 2); -- Wrong, 2 is the internal representation, not the positionpragma
Assert (My_Enum'Pos(Enum1) = 0); -- Rightpragma
Assert (My_Enum'Pos(Enum3) = 2);subtype
My_Enum_Subis
My_Enumrange
Enum1 .. Enum2;pragma
Assert (My_Enum_Sub'Pos (Enum3) = 2); -- Enum3 does not belong to My_Enum_Sub
Another example without representation clause:
type
Coloris
(Red, Blue, White); Object : Color := White;begin
Put (Color'Pos (Object)); -- prints 2, position of White. ...
See also
editThe inverse of the 'Pos attribute is 'Val.
The underlying representation can be obtained using an Unchecked_Conversion, or with the implementation-defined attribute 'Enum_Rep (GNAT).
For a detailed explanation of universal_integer, see Type System: Elaborated Discussion of Types for Signed Integer Types.
Wikibook
editAda Reference Manual
editAda Programming/Attributes/'Position
edit
Description
edit'Position is a record type component attribute. It represents the address offset of the component from the beginning of the record. The value returned is represented in storage units, which is machine-specific. The attribute is closely related to the attributes 'First_Bit and 'Last_Bit. Together they specify the Layout aspect of records.
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Pred
edit
Description
editX'Pred(Y) is an Ada attribute where X is any discrete type and Y is a value of that type. This attribute represents the discrete value that has a position number of one less than the input parameter.
The returned discrete value type is the base type of discrete type. If the input parameter is the First value of the discrete type, then a CONSTRAINT_ERROR exception will be raised.
Example
edittype
My_Enumis
(Enum1, Enum2, Enum3); ...pragma
Assert (My_Enum'Pred (Enum2) = Enum1); -- OKpragma
Assert (My_Enum'Pred (Enum1) = Enum3); -- Wrong
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Preelaborable Initialization
editDescription
editReturns whether the type of S has preelaborable initialization.
Description
editS’Preelaborable_Initialization return Boolean
Ada Programming/Attributes/'Preelaborate Initialization
editDescription
editReturns whether the type of S has preelaborable initialization.
For a nonformal composite subtype S declared within the visible part of a package or a generic package, or a generic formal private subtype or formal derived subtype:
This attribute is of Boolean type, and its value reflects whether the type of S has preelaborable initialization.
Example
editS’Preelaborable_Initialization return Boolean
Ada Programming/Attributes/'Priority
editDescription
editReturns the priority of P.
Denotes a non-aliased component of the protected object P. This component is of type System.Any_Priority and its value is the priority of P. P'Priority denotes a variable if and only if P denotes a variable. A reference to this attribute shall appear only within the body of P.
Example
editP’Priority return System.Any_Priority
Ada Programming/Attributes/'Put Image
editDescription
editWrites an image of the value of X.
Example
editS’Put_Image (Buffer:Ada.Strings.Text_Buffers.Root_Buffer_Type’Class;X)
Ada Programming/Attributes/'Range
edit
Description
editThe meaning of the attribute depends on the meaning of the prefix X.
If X is a scalar subtype, X'Range represents the range of valid values for that subtype, i.e. it is the same as the subtype itself.
If X is a constrained array subtype or an array object, X'Range denotes the index range of X.
In any case, X'Range is equivalent to X'First .. X'Last, but X is only evaluated once.
If X is multidimensional, the attribute needs a static parameter N to identify the N-th index; 'Range (1) is the same as 'Range.
X'Range (N) is equivalent to X'First(N) .. X'Last(N), but X is only evaluated once.
Examples
edittype
Tis
range
1..10; -- T'Range is equal to Ttype
Ais
array
(T)of
S; -- these three A'Range is the same as Ttype
Ais
array
(T'Range)of
S; -- declarationstype
Ais
array
(T'First .. T'Last )of
S; -- are equivalenttype
Bis
array
(Trange
<>)of
S; -- B'Range is illegal (B is unconstrained)subtype
SBis
B (2 .. 5); -- SB'Range is the same as 2 .. 5type
Mis
array
(Boolean, T)of
S; -- M'Range is equivalent to M'Range (1), which is Boolean -- M'Range (2) is the same as T
OA: A; -- OA'Range is the same as T OB: B (2 .. 5); -- OB'Range is equal to 2 .. 5
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Range Length
editDescription
edittyp'Range_Length
for any discrete type yields the number of values represented by the subtype (zero for a null range). The result is static for static subtypes. Range_Length
applied to the index subtype of a one dimensional array always gives the same result as Length
applied to the array itself.
Ada Programming/Attributes/'Read
editDescription
editReads the value of X from Stream.
Example
editS’Read (Stream:access Ada.Streams.Root_Stream_Type’Class;X:out T)
Ada Programming/Attributes/'Reduce
editDescription
editThis attribute represents a reduction expression, and is in the form of a reduction_attribute_reference.
Example
editX|V’Reduce(Reducer, Initial_Value)
Ada Programming/Attributes/'Ref
editDescription
edit’REF denotes the effective address of the first of the storage units allocated to the object. ’REF is not supported for a package, task unit or entry. The two forms for this attribute are X’REF and SYSTEM.ADDRESS’REF(N). Only use X’REF in machine code procedures. Use SYSTEM.ADDRESS’REF(N) anywhere to convert an integer expression to an address.
X’REF
editThe attribute generates a reference to the entity to which it is applied. In X’REF, X must be either a constant, variable, procedure, function, or label. The attribute returns a value of the type MACHINE_CODE.OPERAND. Only use it to designate an operand in a code-statement. Precede the instruction generated by the code-statement in which the attribute occurs by additional instructions needed to facilitate the reference, such as loading a base register. If the declarative section of the procedure contains pragma IMPLICIT_CODE (OFF), a warning generates if additional code is required.
SYSTEM.ADDRESS’REF(N)
editThe effect of this attribute is similar to the effect of an unchecked conversion from integer to address. However, use SYSTEM.ADDRESS’REF(N) instead in the following listed circumstances. In these circumstances, N must be static. In SYSTEM.ADDRESS’REF(N), SYSTEM.ADDRESS must be type SYSTEM.ADDRESS. N must be an expression of type UNIVERSAL_INTEGER. The attribute returns a value of type SYSTEM.ADDRESS, which represents the address designated by N.
- With any of the runtime configuration packages: Use of unchecked conversion in an address clause requires the generation of elaboration code, but the configuration packages are not elaborated.
- In any instance where N is greater than INTEGER’LAST: Such values are required in address clauses that reference the upper portion of memory. To use unchecked conversion in these instances requires the expression be given as a negative integer.
- To place an object at an address, use ’REF.
Example
editIn the following example, the integer_value converts to an address for use in the address representation clause. The form avoids UNCHECKED_CONVERSION and is useful for 32-bit unsigned addresses.
--place an object at an address
for object use at ADDRESS’REF (integer_value)
--to use unsigned addresses
for VECTOR use at SYSTEM.ADDRESS’REF(16#808000d0#);
TOP_OF_MEMORY : SYSTEM.ADDRESS := SYSTEM.ADDRESS’REF(16#FFFFFFFF#);
Ada Programming/Attributes/'Relative Deadline
editDescription
editRelative deadline of P.
Denotes a non-aliased component of the protected object P. This component is of type Ada.Real_Time.Time_Span and its value is the relative deadline of P. P'Relative_Deadline denotes a variable if and only if P denotes a variable. A reference to this attribute shall appear only within the body of P.
Example
editP’Relative_Deadline return Ada.Real_Time.Time_Span
Ada Programming/Attributes/'Remainder
editDescription
editX'Remainder(Y,Z) is an Ada attribute where X is any floating-point type and Y,Z are any instances of that type. This attribute represents the fractional part of this result. Z should never be zero.
The sign of Y may or may not be the same as the sign of the result.
Example
edittype Real is digits 15; Real'Remainder (7.5, 2.3); -- returns 0.6 Real'Remainder (42.97482350828000, 6.283185307179586); -- returns -1.00747364197711
-------------------------------------------------------------------------------- -- Mod function for real numbers -- -- x = The number whose remainder is desired -- y = The divisor -- -- We return x mod y with the same sign as y. -------------------------------------------------------------------------------- function "mod" (x, y : Real) return Real is result : Real := Real'Remainder (x, y); begin if y > 0.0 then if result < 0.0 then result := result + y; end if; else if result > 0.0 then result := result + y; end if; end if; return result; end "mod";
-------------------------------------------------------------------------------------------------- -- Rem function for real numbers -- -- x = The number whose remainder is desired -- y = The divisor -- -- We return x mod y with the same sign as x. -------------------------------------------------------------------------------------------------- function "rem" (x, y : Real) return Real is result : Real := Real'Remainder (x, y); begin if x > 0.0 then if result < 0.0 then result := result + abs y; end if; else if result > 0.0 then result := result - abs y; end if; end if; return result; end "rem";
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Attributes/'Rounding
- Ada Programming/Attributes/'Truncation
- Ada Programming/Attributes/'Unbiased_Rounding
Ada Reference Manual
editAda Programming/Attributes/'Restriction Set
editDescription
editThis attribute allows compile time testing of restrictions that are currently in effect. It is primarily intended for specializing code in the run-time based on restrictions that are active (e.g. don’t need to save fpt registers if restriction No_Floating_Point is known to be in effect), but can be used anywhere.
There are two forms:
System'Restriction_Set (partition_boolean_restriction_NAME)
System'Restriction_Set (No_Dependence => library_unit_NAME);
In the case of the first form, the only restriction names allowed are parameterless restrictions that are checked for consistency at bind time. For a complete list see the subtype System.Rident.Partition_Boolean_Restrictions
.
The result returned is True if the restriction is known to be in effect, and False if the restriction is known not to be in effect. An important guarantee is that the value of a Restriction_Set attribute is known to be consistent throughout all the code of a partition.
This is trivially achieved if the entire partition is compiled with a consistent set of restriction pragmas. However, the compilation model does not require this. It is possible to compile one set of units with one set of pragmas, and another set of units with another set of pragmas. It is even possible to compile a spec with one set of pragmas, and then WITH the same spec with a different set of pragmas. Inconsistencies in the actual use of the restriction are checked at bind time.
In order to achieve the guarantee of consistency for the Restriction_Set pragma, we consider that a use of the pragma that yields False is equivalent to a violation of the restriction.
So for example if you write
if System'Restriction_Set (No_Floating_Point) then
...
else
...
end if;
And the result is False, so that the else branch is executed, you can assume that this restriction is not set for any unit in the partition. This is checked by considering this use of the restriction pragma to be a violation of the restriction No_Floating_Point. This means that no other unit can attempt to set this restriction (if some unit does attempt to set it, the binder will refuse to bind the partition).
Technical note: The restriction name and the unit name are intepreted entirely syntactically, as in the corresponding Restrictions pragma, they are not analyzed semantically, so they do not have a type.
Ada Programming/Attributes/'Result
editDescription
editWithin a postcondition expression for F, denotes the return object of the function call for which the postcondition expression is evaluated.
Within a postcondition expression for F, denotes the return object of the function call for which the postcondition expression is evaluated. The type of this attribute is that of the result subtype of the function or access-to-function type except within a Post'Class postcondition expression for a function with a controlling result or with a controlling access result; in those cases the type of the attribute is described above as part of the Name Resolution Rules for Post'Class.
Example
editF’Result return X
Ada Programming/Attributes/'Round
editDescription
editFixed-point value obtained by rounding X (away from 0, if X is midway between two values).
The function returns the value obtained by rounding X (away from 0, if X is midway between two values of the type of S).
Example
editF’Round (X) return S
Ada Programming/Attributes/'Rounding
edit
Description
editX'Rounding(Y) is an Ada attribute where X is any floating-point type and Y is any instance of that type. This attribute represents the closest integer value to Y. If Y is exactly between two integer values (e.g. 1.5), then the result is the number farthest away from zero (e.g. 1.5 => 2.0, -1.5 => -2.0).
Example
editW : Float := -1.5; X : Float := 1.5; Y : Float := 1.0; Z : Float := 1.999; ...pragma
Assert (Float'Rounding(W) = -2.0); -- OKpragma
Assert (Float'Rounding(X) = 2.0); -- OKpragma
Assert (Float'Rounding(Y) = 1.0); -- OKpragma
Assert (Float'Rounding(Z) = 2.0); -- OKpragma
Assert (Float'Rounding(W) = -1.0); -- Wrongpragma
Assert (Float'Rounding(X) = 1.0); -- Wrong
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Attributes/'Ceiling
- Ada Programming/Attributes/'Floor
- Ada Programming/Attributes/'Unbiased_Rounding
Ada Reference Manual
edit- 13.3 Operational and Representation Attributes (Annotated)
- Annex K Language-Defined Attributes (Annotated)
A Wikibookian believes this page should be split into smaller pages with a narrower subtopic. You can help by splitting this big page into smaller ones. Please make sure to follow the naming policy. Dividing books into smaller sections can provide more focus and allow each one to do one thing well, which benefits everyone. |
Ada Programming/Attributes/'Safe Emax
editDescription
editThe Safe_Emax
attribute is provided for compatibility with Ada 83. See the Ada 83 reference manual for an exact description of the semantics of this attribute.
Ada Programming/Attributes/'Safe First
editDescription
editReturns lower bound of the safe range.
Yields the lower bound of the safe range (see 3.5.7) of the type T. If the Numerics Annex is not supported, the value of this attribute is implementation defined.
The value of this attribute is of the type universal_real.
Example
editS’Safe_First return universal_real
Ada Programming/Attributes/'Safe Large
editDescription
editThe Safe_Large
attribute is provided for compatibility with Ada 83. See the Ada 83 reference manual for an exact description of the semantics of this attribute.
Ada Programming/Attributes/'Safe Last
editDescription
editReturns upper bound of the safe range.
Yields the upper bound of the safe range (see 3.5.7) of the type T. If the Numerics Annex is not supported, the value of this attribute is implementation defined. The value of this attribute is of the type universal_real.
Example
editS’Safe_Last return universal_real
Ada Programming/Attributes/'Safe Small
editDescription
editThe Safe_Small
attribute is provided for compatibility with Ada 83. See the Ada 83 reference manual for an exact description of the semantics of this attribute.
Ada Programming/Attributes/'Scalar Storage Order
editDescription
edit
For every array or record type S
, the representation attribute Scalar_Storage_Order
denotes the order in which storage elements that make up scalar components are ordered within S. The value given must be a static expression of type System.Bit_Order. The following is an example of the use of this feature:
-- Component type definitions
subtype Yr_Type is Natural range 0 .. 127;
subtype Mo_Type is Natural range 1 .. 12;
subtype Da_Type is Natural range 1 .. 31;
-- Record declaration
type Date is record
Years_Since_1980 : Yr_Type;
Month : Mo_Type;
Day_Of_Month : Da_Type;
end record;
-- Record representation clause
for Date use record
Years_Since_1980 at 0 range 0 .. 6;
Month at 0 range 7 .. 10;
Day_Of_Month at 0 range 11 .. 15;
end record;
-- Attribute definition clauses
for Date'Bit_Order use System.High_Order_First;
for Date'Scalar_Storage_Order use System.High_Order_First;
-- If Scalar_Storage_Order is specified, it must be consistent with
-- Bit_Order, so it's best to always define the latter explicitly if
-- the former is used.
Other properties are as for the standard representation attribute Bit_Order
defined by Ada RM 13.5.3(4). The default is System.Default_Bit_Order
.
For a record type T
, if T'Scalar_Storage_Order
is specified explicitly, it shall be equal to T'Bit_Order
. Note: this means that if a Scalar_Storage_Order
attribute definition clause is not confirming, then the type’s Bit_Order
shall be specified explicitly and set to the same value.
Derived types inherit an explicitly set scalar storage order from their parent types. This may be overridden for the derived type by giving an explicit scalar storage order for it. However, for a record extension, the derived type must have the same scalar storage order as the parent type.
A component of a record type that is itself a record or an array and that does not start and end on a byte boundary must have have the same scalar storage order as the record type. A component of a bit-packed array type that is itself a record or an array must have the same scalar storage order as the array type.
No component of a type that has an explicit Scalar_Storage_Order
attribute definition may be aliased.
A confirming Scalar_Storage_Order
attribute definition clause (i.e. with a value equal to System.Default_Bit_Order
) has no effect.
If the opposite storage order is specified, then whenever the value of a scalar component of an object of type S
is read, the storage elements of the enclosing machine scalar are first reversed (before retrieving the component value, possibly applying some shift and mask operatings on the enclosing machine scalar), and the opposite operation is done for writes.
In that case, the restrictions set forth in 13.5.1(10.3/2) for scalar components are relaxed. Instead, the following rules apply:
- the underlying storage elements are those at positions
(position + first_bit / storage_element_size) .. (position + (last_bit + storage_element_size - 1) / storage_element_size)
- the sequence of underlying storage elements shall have a size no greater than the largest machine scalar
- the enclosing machine scalar is defined as the smallest machine scalar starting at a position no greater than
position + first_bit / storage_element_size
and covering storage elements at least up toposition + (last_bit + storage_element_size - 1) / storage_element_size
- the position of the component is interpreted relative to that machine scalar.
If no scalar storage order is specified for a type (either directly, or by inheritance in the case of a derived type), then the default is normally the native ordering of the target, but this default can be overridden using pragma Default_Scalar_Storage_Order
.
If a component of T
is itself of a record or array type, the specfied Scalar_Storage_Order
does not apply to that nested type: an explicit attribute definition clause must be provided for the component type as well if desired.
Representation changes that explicitly or implicitly toggle the scalar storage order are not supported and may result in erroneous execution of the program, except when performed by means of an instance of Ada.Unchecked_Conversion
.
In particular, overlays are not supported and a warning is given for them:
type Rec_LE is record
I : Integer;
end record;
for Rec_LE use record
I at 0 range 0 .. 31;
end record;
for Rec_LE'Bit_Order use System.Low_Order_First;
for Rec_LE'Scalar_Storage_Order use System.Low_Order_First;
type Rec_BE is record
I : Integer;
end record;
for Rec_BE use record
I at 0 range 0 .. 31;
end record;
for Rec_BE'Bit_Order use System.High_Order_First;
for Rec_BE'Scalar_Storage_Order use System.High_Order_First;
R_LE : Rec_LE;
R_BE : Rec_BE;
for R_BE'Address use R_LE'Address;
warning: overlay changes scalar storage order [enabled by default]
In most cases, such representation changes ought to be replaced by an instantiation of a function or procedure provided by GNAT.Byte_Swapping
.
Note that the scalar storage order only affects the in-memory data representation. It has no effect on the representation used by stream attributes.
Note that debuggers may be unable to display the correct value of scalar components of a type for which the opposite storage order is specified.
Ada Programming/Attributes/'Scale
editDescription
editPosition of the fixed-point relative to the rightmost significant digits of values of subtype S.
S'Scale denotes the scale of the subtype S, defined as the value N such that S'Delta = 10.0**(–N). The scale indicates the position of the point relative to the rightmost significant digits of values of subtype S. The value of this attribute is of the type universal_integer.
Example
editS’Scale return universal_integer
Ada Programming/Attributes/'Scaling
editDescription
editScaling by a power of the hardware radix.
Let v be the value X · T'Machine_RadixAdjustment. If v is a machine number of the type T, or if |v| ≥ T'Model_Small, the function yields v; otherwise, it yields either one of the machine numbers of the type T adjacent to v. Constraint_Error is optionally raised if v is outside the base range of S. A zero result has the sign of X when S'Signed_Zeros is True.
Example
editS’Scaling (X:T;Adjustment:universal_integer) return T
Ada Programming/Attributes/'Signed Zeros
editDescription
editTrue if positive and negative signed zeros are representable.
Yields the value True if the hardware representation for the type T has the capability of representing both positively and negatively signed zeros, these being generated and used by the predefined operations of the type T as specified in IEC 559:1989; yields the value False otherwise. The value of this attribute is of the predefined type Boolean.
Example
editS’Signed_Zeros return Boolean
Ada Programming/Attributes/'Simple Storage Pool
editDescription
edit
For every nonformal, nonderived access-to-object type Acc
, the representation attribute Simple_Storage_Pool
may be specified via an attribute_definition_clause (or by specifying the equivalent aspect):
My_Pool : My_Simple_Storage_Pool_Type;
type Acc is access My_Data_Type;
for Acc'Simple_Storage_Pool use My_Pool;
The name given in an attribute_definition_clause for the Simple_Storage_Pool
attribute shall denote a variable of a ‘simple storage pool type’ (see pragma ).
The use of this attribute is only allowed for a prefix denoting a type for which it has been specified. The type of the attribute is the type of the variable specified as the simple storage pool of the access type, and the attribute denotes that variable.
It is illegal to specify both Storage_Pool
and Simple_Storage_Pool
for the same access type.
If the Simple_Storage_Pool
attribute has been specified for an access type, then applying the Storage_Pool
attribute to the type is flagged with a warning and its evaluation raises the exception Program_Error
.
If the Simple_Storage_Pool attribute has been specified for an access type S
, then the evaluation of the attribute S'Storage_Size
returns the result of calling Storage_Size (S'Simple_Storage_Pool)
, which is intended to indicate the number of storage elements reserved for the simple storage pool. If the Storage_Size function has not been defined for the simple storage pool type, then this attribute returns zero.
If an access type S
has a specified simple storage pool of type SSP
, then the evaluation of an allocator for that access type calls the primitive Allocate
procedure for type SSP
, passing S'Simple_Storage_Pool
as the pool parameter. The detailed semantics of such allocators is the same as those defined for allocators in section 13.11 of the , with the term simple storage pool substituted for storage pool.
If an access type S
has a specified simple storage pool of type SSP
, then a call to an instance of the Ada.Unchecked_Deallocation
for that access type invokes the primitive Deallocate
procedure for type SSP
, passing S'Simple_Storage_Pool
as the pool parameter. The detailed semantics of such unchecked deallocations is the same as defined in section 13.11.2 of the Ada Reference Manual, except that the term simple storage pool is substituted for storage pool.
Ada Programming/Attributes/'Size
edit
Description
editR'Size is a representation attribute used to get the number of bits of an object or type:
- When applied to an object, 'Size yields the actual number of bits allocated to store the object.
- When applied to a subtype, 'Size yields the smallest n such that all values fit in the range 0 .. 2n-1 for only positive values, else -2n-1 .. 2n-1-1.
The 'Size attribute may also be used in an attribute definition clause to set the size for a first subtype. In special cases, it is even possible to force a biased representation by using a smaller value than the n above.
Examples
editThis subtype allows a biased representation with only three bits because it comprises only eight values:
type
Tis
range
1000 .. 1007;for
T'Sizeuse
3;
Without the size clause, T'Size would return 10 because 210-1 = 1023.
with
Ada.Text_IO;procedure
Attributes_Sizeis
package
T_IOrenames
Ada.Text_IO;package
I_IOis
new
Ada.Text_IO.Integer_IO (Integer); A_Boolean :constant
Boolean := True;begin
T_IO.Put ("Size of Boolean type = "); -- An enumeration with I_IO.Put (Boolean'Size); -- 2 values fits into T_IO.New_Line; -- 1 bit. T_IO.Put ("Size of Boolean Object = "); -- it is more efficient I_IO.Put (A_Boolean'Size); -- to store a boolean T_IO.New_Line; -- as an entire byteend
Attributes_Size;
The output with GNAT 10.2.0 will be:
Size of Boolean type = 1 Size of Boolean Object = 8
Try it yourself and see how your compiler does.
The value of Size can also be specified using an attribute definition clause. For example, the following declarations specify a C99 compatible bool:
type
Boolis
new
Boolean;for
Bool'Sizeuse
Interfaces.C.int'Size;
Incorrect usages
editA common Ada programming mistake is to assume that specifying 'Size for a type T forces the compiler to allocate exactly this number of bits for objects of this type. This is not true. The specified T'Size will force the compiler to use this size for components in packed arrays and records and in Unchecked_Conversion, but the compiler is still free to allocate more bits for stand-alone objects.
Use 'Size on the object itself to force the object to the specified value.
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Attributes/'Component Size
- Ada Programming/Attributes/'Max Size In Storage Elements
- Ada Programming/Attributes/'Value Size (implementation defined)
- Ada Programming/Attributes/'Object Size (implementation defined)
Ada 83 Reference Manual
editAda 95 Reference Manual
edit- 13.3: Operational and Representation Attributes [Annotated]
- Annex K: Language-Defined Attributes [Annotated]
Ada 2005 Reference Manual
edit- 13.3: Operational and Representation Attributes [Annotated]
- Annex K: Language-Defined Attributes [Annotated]
Ada 2012 Reference Manual
editAda Programming/Attributes/'Size:3
editA common Ada programming mistake is to assume that specifying 'Size for a type T forces the compiler to allocate exactly this number of bits for objects of this type. This is not true. The specified T'Size will force the compiler to use this size for components in packed arrays and records and in Unchecked_Conversion, but the compiler is still free to allocate more bits for stand-alone objects.
Use 'Size on the object itself to force the object to the specified value.
Ada Programming/Attributes/'Small
editDescription
editSmall of the fixed-point type.
S'Small denotes the small of the type of S. The value of this attribute is of the type universal_real.
Example
editS’Small return universal_real
Ada Programming/Attributes/'Small Denominator
editDescription
edittyp'Small_Denominator
for any fixed-point subtype yields the denominator in the representation of typ'Small
as a rational number with coprime factors (i.e. as an irreducible fraction).
Ada Programming/Attributes/'Small Numerator
editDescription
edittyp'Small_Numerator
for any fixed-point subtype yields the numerator in the representation of typ'Small
as a rational number with coprime factors (i.e. as an irreducible fraction).
Ada Programming/Attributes/'Storage Pool
editDescription
editReturns Storage pool of the access subtype.
Denotes the storage pool of the type of S. The type of this attribute is Root_Storage_Pool'Class.
Example
editS’Storage_Pool return Root_Storage_Pool’Class
Ada Programming/Attributes/'Storage Size
editDescription
editNumber of storage elements reserved for the storage pool.
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.)
Example
editS’Storage_Size return universal_integer
Ada Programming/Attributes/'Storage Unit
editDescription
editStandard'Storage_Unit
(Standard
is the only allowed prefix) provides the same value as System.Storage_Unit
.
Ada Programming/Attributes/'Stream Size
editDescription
editNumber of bits read from or written to a stream by the default implementations of S’Read and S’Write.
If S is definite, denotes the size (in bits) that the implementation would choose for the following objects of subtype S:
- A record component of subtype S when the record type is packed.
- The formal parameter of an instance of Unchecked_Conversion that converts from subtype S to some other subtype.
If S is indefinite, the meaning is implementation defined. The value of this attribute is of the type universal_integer.
Example
editS’Stream_Size return universal_integer
Ada Programming/Attributes/'Stub Type
editDescription
editThe GNAT implementation of remote access-to-classwide types is organized as described in AARM section E.4 (20.t): a value of an RACW type (designating a remote object) is represented as a normal access value, pointing to a “stub” object which in turn contains the necessary information to contact the designated remote object. A call on any dispatching operation of such a stub object does the remote call, if necessary, using the information in the stub object to locate the target partition, etc.
For a prefix T
that denotes a remote access-to-classwide type, T'Stub_Type
denotes the type of the corresponding stub objects.
By construction, the layout of T'Stub_Type
is identical to that of type RACW_Stub_Type
declared in the internal implementation-defined unit System.Partition_Interface
. Use of this attribute will create an implicit dependency on this unit.
Ada Programming/Attributes/'Succ
edit
Description
editX'Succ(Y) is an Ada attribute where X is any discrete type and Y is a value of that type. This attribute represents the discrete value that has a position number of one greater than the input parameter.
The returned discrete value type is the base type of discrete type. If the input parameter is the Last value of the discrete type, then a CONSTRAINT_ERROR exception will be raised.
Example
edittype
My_Enumis
(Enum1, Enum2, Enum3); ...pragma
Assert (My_Enum'Succ(Enum2) = Enum3); -- OKpragma
Assert (My_Enum'Succ(Enum3) = Enum1); -- Wrong
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'System Allocator Alignment
editDescription
editStandard'System_Allocator_Alignment
(Standard
is the only allowed prefix) provides the observable guaranteed to be honored by the system allocator (malloc). This is a static value that can be used in user storage pools based on malloc either to reject allocation with alignment too large or to enable a realignment circuitry if the alignment request is larger than this value.
Ada Programming/Attributes/'Tag
edit
Description
editX'Tag is an Ada attribute where X is any tagged type. This attribute returns a value of the private type Ada.Tags.Tag which identifies the tagged type.
This attribute is useful to check for membership of a type in a class hierarchy. It can also be used if it is known the type is in a class hierarchy and type-specific processing must take place.
Example
editRef : My_Tagged_Type_Reference; ...if
Ref.all
in
My_Tagged_Type'Classthen
-- The object pointed at by Ref is in class hierarchy that is rooted at My_Tagged_Type.if
Ref.all
'Tag = My_Tagged_Type'Tagthen
-- Object is of type My_Tagged_Type.else
-- Object is of some other type in the hierarchy.end
if
;else
-- Object is not in the class hierarchy rooted at My_Tagged_Type (it might be of a progenitor type though).end
if
;
See also
editWikibook
editAda Reference Manual
editAda Programming/Attributes/'Target Name
editDescription
editStandard'Target_Name
(Standard
is the only allowed prefix) provides a static string value that identifies the target for the current compilation. For GCC implementations, this is the standard gcc target name without the terminating slash (for example, GNAT 5.0 on windows yields “i586-pc-mingw32msv”).
Ada Programming/Attributes/'Task ID
editDescription
editFor a non-passive task object or a value, X, X’TASK_ID yields the unique task ID associated with the task. The value of this attribute is of the type SYSTEM.TASK_ID. If the task objector value X denotes a passive task, the result is the passive task header record object associated with the passive task. The result type is then of type SYSTEM.PASSIVE_TASK_ID.
Ada Programming/Attributes/'Terminated
edit
Description
editX'Terminated is an Ada attribute where X is any task object. This attribute indicates if X has terminated (true) or not (false).
Be warned—calling X'Terminated can result in a race condition. X'Terminated may be false at the time the attribute value is read, but it may become true at the time action is taken based on the value read. Once X'Terminated is true, however, it can be expected to stay true.
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Tasking
- Ada Programming/Attributes/'Callable
Ada Reference Manual
editAda Programming/Attributes/'To Address
edit
Description
editSystem'To_Address (X) is a GNAT specific attribute with the same purpose of function System.Storage_Elements.To_Address. The only difference is that it can be used in preelaborated units where non-static calls are not allowed. X is a value of that type System.Storage_Elements.Integer_Address (an implementation-defined integer type), and note that this attribute is not applied to the type of X but always to package System.
Example
editUsing the standard Ada To_Address function:
for
Sensor'Address use System.Storage_Elements.To_Address (16#0FF2_1234#);
Using the GNAT specific To_Address attribute:
for
Sensor'Address use System'To_Address (16#0FF2_1234#);
See also
editWikibook
editGNAT Reference Manual
editAda Programming/Attributes/'To Any
editDescription
editThis internal attribute is used for the generation of remote subprogram stubs in the context of the Distributed Systems Annex.
Ada Programming/Attributes/'Truncation
edit
Description
editX'Truncation(Y) is an Ada attribute where X is any floating-point type and Y is any instance of that type. This attribute represents the truncation of Y to an integer value.
If Y is negative, then Truncation is equivalent to X'Ceiling(Y). If Y is positive, then Truncation is equivalent to X'Floor(Y).
Example
editX : Float := 1.5; Y : Float := 1.0; Z : Float := -1.999;pragma
Assert (Float'Truncation(X) = 1.0); -- Okpragma
Assert (Float'Truncation(Y) = 1.0); -- Okpragma
Assert (Float'Truncation(Z) = -1.0); -- Okpragma
Assert (Float'Truncation(Z) = -2.0); -- Wrong
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Attributes/'Ceiling
- Ada Programming/Attributes/'Floor
- Ada Programming/Attributes/'Rounding
- Ada Programming/Attributes/'Remainder
- Ada Programming/Attributes/'Unbiased_Rounding
Ada Reference Manual
editAda Programming/Attributes/'TypeCode
editDescription
editThis internal attribute is used for the generation of remote subprogram stubs in the context of the Distributed Systems Annex.
Ada Programming/Attributes/'Type Class
editDescription
edittyp'Type_Class
for any type or subtype yields the value of the type class for the full type of . If is a generic formal type, the value is the value for the corresponding actual subtype. The value of this attribute is of type System.Aux_DEC.Type_Class
, which has the following definition:
type Type_Class is
(Type_Class_Enumeration,
Type_Class_Integer,
Type_Class_Fixed_Point,
Type_Class_Floating_Point,
Type_Class_Array,
Type_Class_Record,
Type_Class_Access,
Type_Class_Task,
Type_Class_Address);
Protected types yield the value Type_Class_Task
, which thus applies to all concurrent types. This attribute is designed to be compatible with the DEC Ada 83 attribute of the same name.
Ada Programming/Attributes/'Type Key
editDescription
editThe Type_Key
attribute is applicable to a type or subtype and yields a value of type Standard.String containing encoded information about the type or subtype. This provides improved compatibility with other implementations that support this attribute.
Ada Programming/Attributes/'Unbiased Rounding
edit
Description
editX'Unbiased_Rounding(Y) is an Ada attribute where X is any floating-point type and Y is any instance of that type. This attribute represents the closest integer value to Y. If Y is exactly between two integer values (e.g. 1.5), then the result is the even value (e.g. 2.0).
Example
editX : Float := 1.5; Y : Float := 1.0; Z : Float := 1.999; ...pragma
Assert(Float'Unbiased_Rounding(X) = 2.0); -- OKpragma
Assert(Float'Unbiased_Rounding(Y) = 1.0); -- OKpragma
Assert(Float'Unbiased_Rounding(Z) = 2.0); -- OKpragma
Assert(Float'Unbiased_Rounding(X) = 1.0); -- Wrong ... X := 2.5;pragma
Assert(Float'Unbiased_Rounding(X) = 2.0 ); -- OKpragma
Assert(Float'Unbiased_Rounding(X) = 3.0 ); -- Wrong
See also
editWikibook
edit- Ada Programming
- Ada Programming/Attributes
- Ada Programming/Attributes/'Ceiling
- Ada Programming/Attributes/'Floor
- Ada Programming/Attributes/'Rounding
Ada Reference Manual
editAda Programming/Attributes/'Unchecked Access
editDescription
editSame as X’Access but lacks accessibility rules/checks.
All rules and semantics that apply to X'Access apply also to X'Unchecked_Access, except that, for the purposes of accessibility rules and checks, it is as if X were declared immediately within a library package.
Example
editX’Unchecked_Access (X:T) return access type
Ada Programming/Attributes/'Unconstrained Array
editDescription
editThe Unconstrained_Array
attribute can be used with a prefix that denotes any type or subtype. It is a static attribute that yields True
if the prefix designates an unconstrained array, and False
otherwise. In a generic instance, the result is still static, and yields the result of applying this test to the generic actual.
Ada Programming/Attributes/'Universal Literal String
editDescription
editThe prefix of Universal_Literal_String
must be a named number. The static result is the string consisting of the characters of the number as defined in the original source. This allows the user program to access the actual text of named numbers without intermediate conversions and without the need to enclose the strings in quotes (which would preclude their use as numbers).
For example, the following program prints the first 50 digits of pi:
with Text_IO; use Text_IO;
with Ada.Numerics;
procedure Pi is
begin
Put (Ada.Numerics.Pi'Universal_Literal_String);
end;
Ada Programming/Attributes/'Unrestricted Access
editDescription
editThe Unrestricted_Access
attribute is similar to Access
except that all accessibility and aliased view checks are omitted. This is a user-beware attribute.
For objects, it is similar to Address
, for which it is a desirable replacement where the value desired is an access type. In other words, its effect is similar to first applying the Address
attribute and then doing an unchecked conversion to a desired access type.
For subprograms, P'Unrestricted_Access
may be used where P'Access
would be illegal, to construct a value of a less-nested named access type that designates a more-nested subprogram. This value may be used in indirect calls, so long as the more-nested subprogram still exists; once the subprogram containing it has returned, such calls are erroneous. For example:
package body P is
type Less_Nested is not null access procedure;
Global : Less_Nested;
procedure P1 is
begin
Global.all;
end P1;
procedure P2 is
Local_Var : Integer;
procedure More_Nested is
begin
... Local_Var ...
end More_Nested;
begin
Global := More_Nested'Unrestricted_Access;
P1;
end P2;
end P;
When P1 is called from P2, the call via Global is OK, but if P1 were called after P2 returns, it would be an erroneous use of a dangling pointer.
For objects, it is possible to use Unrestricted_Access
for any type. However, if the result is of an access-to-unconstrained array subtype, then the resulting pointer has the same scope as the context of the attribute, and must not be returned to some enclosing scope. For instance, if a function uses Unrestricted_Access
to create an access-to-unconstrained-array and returns that value to the caller, the result will involve dangling pointers. In addition, it is only valid to create pointers to unconstrained arrays using this attribute if the pointer has the normal default ‘fat’ representation where a pointer has two components, one points to the array and one points to the bounds. If a size clause is used to force ‘thin’ representation for a pointer to unconstrained where there is only space for a single pointer, then the resulting pointer is not usable.
In the simple case where a direct use of Unrestricted_Access attempts to make a thin pointer for a non-aliased object, the compiler will reject the use as illegal, as shown in the following example:
with System; use System;
procedure SliceUA2 is
type A is access all String;
for A'Size use Standard'Address_Size;
procedure P (Arg : A) is
begin
null;
end P;
X : String := "hello world!";
X2 : aliased String := "hello world!";
AV : A := X'Unrestricted_Access; -- ERROR
|
>>> illegal use of Unrestricted_Access attribute
>>> attempt to generate thin pointer to unaliased object
begin
P (X'Unrestricted_Access); -- ERROR
|
>>> illegal use of Unrestricted_Access attribute
>>> attempt to generate thin pointer to unaliased object
P (X(7 .. 12)'Unrestricted_Access); -- ERROR
|
>>> illegal use of Unrestricted_Access attribute
>>> attempt to generate thin pointer to unaliased object
P (X2'Unrestricted_Access); -- OK
end;
but other cases cannot be detected by the compiler, and are considered to be erroneous. Consider the following example:
with System; use System;
with System; use System;
procedure SliceUA is
type AF is access all String;
type A is access all String;
for A'Size use Standard'Address_Size;
procedure P (Arg : A) is
begin
if Arg'Length /= 6 then
raise Program_Error;
end if;
end P;
X : String := "hello world!";
Y : AF := X (7 .. 12)'Unrestricted_Access;
begin
P (A (Y));
end;
A normal unconstrained array value or a constrained array object marked as aliased has the bounds in memory just before the array, so a thin pointer can retrieve both the data and the bounds. But in this case, the non-aliased object X
does not have the bounds before the string. If the size clause for type A
were not present, then the pointer would be a fat pointer, where one component is a pointer to the bounds, and all would be well. But with the size clause present, the conversion from fat pointer to thin pointer in the call loses the bounds, and so this is erroneous, and the program likely raises a Program_Error
exception.
In general, it is advisable to completely avoid mixing the use of thin pointers and the use of Unrestricted_Access
where the designated type is an unconstrained array. The use of thin pointers should be restricted to cases of porting legacy code that implicitly assumes the size of pointers, and such code should not in any case be using this attribute.
Another erroneous situation arises if the attribute is applied to a constant. The resulting pointer can be used to access the constant, but the effect of trying to modify a constant in this manner is not well-defined. Consider this example:
P : constant Integer := 4;
type R is access all Integer;
RV : R := P'Unrestricted_Access;
..
RV.all := 3;
Here we attempt to modify the constant P from 4 to 3, but the compiler may or may not notice this attempt, and subsequent references to P may yield either the value 3 or the value 4 or the assignment may blow up if the compiler decides to put P in read-only memory. One particular case where Unrestricted_Access
can be used in this way is to modify the value of an in
parameter:
procedure K (S : in String) is
type R is access all Character;
RV : R := S (3)'Unrestricted_Access;
begin
RV.all := 'a';
end;
In general this is a risky approach. It may appear to “work” but such uses of Unrestricted_Access
are potentially non-portable, even from one version of GNAT to another, so are best avoided if possible.