Ada Libraries and Attributes


Ada Libraries and Attributes

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

Permission is granted to copy, distribute, and/or modify this document under the terms of the Creative Commons Attribution-ShareAlike 3.0 License.



Aspects

edit
S with Aggregate => (aggregate)

Description

edit

Mechanism to define user-defined aggregates.


 
Ada. Time-tested, safe and secure.


with No_Return

Description

edit

Specifying 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

edit
procedure P ( … ) with No_Return;
procedure Q (x : out … ) is
begin
  if Cond then
    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 here
end Q;

Portability

edit

The 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

edit

Wikibook

edit

Ada Reference Manual

edit

References

edit
  1. AI05-0229
  2. AI95-00329
with 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

edit

This 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_designator use expression;
   | for entity_name'attribute_designator use 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

edit

If 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

E – O

edit

P – Z

edit

List of implementation defined aspects

edit

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

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada 2012

edit

Ada 2022

edit

References

edit


Ada Programming/Aspects/Aggregate

edit
S with Aggregate => (aggregate)

Description

edit

Mechanism to define user-defined aggregates.

Ada Programming/Aspects/No Return

edit

 
Ada. Time-tested, safe and secure.


with No_Return

Description

edit

Specifying 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

edit
procedure P ( … ) with No_Return;
procedure Q (x : out … ) is
begin
  if Cond then
    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 here
end Q;

Portability

edit

The 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

edit

Wikibook

edit

Ada Reference Manual

edit

References

edit
  1. AI05-0229
  2. AI95-00329

Ada Programming/Aspects/Write

edit
with Ada.Text_IO;

procedure Hello is
begin
  Ada.Text_IO.Put_Line("Hello World!");
end Hello;

Attributes

edit

Ada Programming/Attributes/'Abort Signal

edit

Description

edit

Provides 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

edit

Standard'Abort_Signal (Standard is the only allowed prefix).

Ada Programming/Attributes/'Access

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
 type General_Pointer  is access all      Integer;
 type Constant_Pointer is 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_Procedure is access procedure (Id  : Integer;
                                             Text: String);
 procedure Process_Event (Id  : Integer;
                         Text: String);

 My_Callback: Callback_Procedure := Process_Event'Access;

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Address

edit

 
Ada. Time-tested, safe and secure.


Attribute Definition Clause

edit

X'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'Address use System.Storage_Elements.To_Address (16#8000_05C4#);

It's not recommended to use Integer_32 in this case.

Aspect Specification

edit

The 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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Address Size

edit

Description

edit

Is 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

edit

Standard'Address_Size (Standard is the only allowed prefix)

Ada Programming/Attributes/'Adjacent

edit

 
Ada. Time-tested, safe and secure.


Description

edit

S'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

edit
with 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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Aft

edit

 
Ada. Time-tested, safe and secure.

S'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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Alignment

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Asm Input

edit

Description

edit

The 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

edit

Ada Programming/Attributes/'Asm Output

edit

Description

edit

The 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

edit

Ada Programming/Attributes/'Atomic Always Lock Free

edit

Description

edit

The 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

 
Ada. Time-tested, safe and secure.


Description

edit

Represents 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

edit

The standard states that the range of T'Base:

  1. includes the value 0
  2. is symmetric about zero, with possibly an extra negative value
  3. includes all of the values in the subtype T

So for example, if T is:

 type T is 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'Base is 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 T is T'Base range 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_Base is 0 .. 2 * T_Last;
  subtype T is T_Base range 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 T is 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

edit

An enumeration type is its own base type, so given this type:

  type ET is (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_Base is (ET_Base_First, A, B, C, ET_Base_Last);
 subtype ET is ET_Base range 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'Last loop
     ... --  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_ET is new ET_Base range A .. C;

 Correct: constant Boolean := New_ET'Base'First = ET_Base_First;

Note that here ET_BASE_First is of type New_ET.

Example

edit

If you declare:

type My_Enum is (Enum1, Enum2, Enum3);

and

subtype Sub_Enum is My_Enum range Enum1 .. Enum2;

then Sub_Enum'Base'Last is Enum3.

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Bit

edit

Description

edit

obj'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

edit

Ada Programming/Attributes/'Bit Order

edit

 
Ada. Time-tested, safe and secure.


Description

edit

R'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:

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

edit

Storage 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

edit

Ada 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 Rec is record
  A at 0 range 0 .. 5;
  B at 0 range 6 .. 7;
end record;
for Rec'Bit_Order use 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 Rec is record
  A at 0 range 2 .. 7;
  B at 0 range 0 .. 1;
end record;
for Rec'Bit_Order use 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 Rec is record
  A at 0 range 0 .. 5;
  B at 0 range 6 .. 9;
end record;
for Rec'Bit_Order use 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 Rec is record
  A at 0 range 0 ..  7;
  B at 1 range 0 .. 15;
end record;
for Rec'Bit_Order use 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

edit

For 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 T use record
  I at 0 range  0 .. 15;  -- at 0 range 0 .. 15
  A at 2 range  0 .. 12;  -- at 2 range 0 .. 12
  B at 2 range 13 .. 17;  -- at 3 range 5 ..  9
  C at 2 range 18 .. 23;  -- at 4 range 2 ..  7
  D at 5 range  0 ..  7;  -- at 5 range 0 ..  7
end 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 T use record
  I at 0 range  0 .. 15;
  A at 2 range  0 .. 12;
  B at 2 range 13 .. 17;
  C at 2 range 18 .. 23;
  D at 5 range  0 ..  7;
end record;
for T'Bit_Order use 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 T use record
  I at 0 range  0 .. 15;
  A at 2 range  0 .. 12;
  B at 2 range 13 .. 17;
  C at 2 range 18 .. 23;
--D at 5 range  0 ..  7;
  D at 2 range 24 .. 31;
end record;
for T'Bit_Order use 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

edit

Let 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

edit

The following two sets of representation clauses specify the same register layout in any machine / compiler (Ada 2005 and later):

type Device_Register is
    record
       Ready : Status_Flag;
       Error : Error_Flag;
       Data  : Unsigned_16;
    end record;

for  Device_Register use
    record
       Ready at 0 range  0 .. 0;
       Error at 0 range  1 .. 1;
       -- Reserved bits
       Data  at 0 range 16 .. 31;
    end record;
for Device_Register'Size      use 32;
for Device_Register'Bit_Order use 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_Register is
    record
       Ready : Status_Flag;
       Error : Error_Flag;
       Data  : Unsigned_16;
    end record;

for  Device_Register use
    record
       Ready at 0 range 31 .. 31;   -- Bit numbering has changed
       Error at 0 range 30 .. 30;   -- Bit numbering has changed
       -- Reserved bits
       Data  at 0 range  0 .. 15;   -- Bit numbering has changed (but byte order is not affected)
    end record;
for Device_Register'Size      use 32;
for Device_Register'Bit_Order use System.High_Order_First; -- Reverse bit order

pragma 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

edit

The '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
  1. 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)]

  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)
  3. 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.
  4. 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)
  5. 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

edit

Record 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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Rationale

edit

References and notes

edit

Further reading

edit

Ada Programming/Attributes/'Bit Order:3

edit

The '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
  1. 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.
  2. 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)
  3. 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

edit

Description

edit

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

edit

Ada Programming/Attributes/'Body Version

edit

Description

edit

Yields 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

edit
PBody_Version return String

Ada Programming/Attributes/'Callable

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Caller

edit

Description

edit

Identifies 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

edit
ECaller return Task_ID

Ada Programming/Attributes/'Ceiling

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
X : Float := 1.5;
Y : Float := 1.0;
Z : Float := 1.999;
... 
pragma Assert (Float'Ceiling(X) = 2.0 );  -- OK
pragma Assert (Float'Ceiling(Y) = 1.0 );  -- OK
pragma Assert (Float'Ceiling(Z) = 1.0 );  -- Wrong

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Class

edit

 
Ada. Time-tested, safe and secure.


The Class attribute denotes the class wide type of the given tagged type.

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Code Address

edit

Description

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

edit

Ada Programming/Attributes/'Compiler Version

edit

Description

edit

Standard'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

 
Ada. Time-tested, safe and secure.


Description

edit

R'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

edit

Wikibook

edit

Ada 95 Reference Manual

edit

Ada 2005 Reference Manual

edit


Ada Programming/Attributes/'Compose

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
with 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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Constrained

edit

Description

edit

True 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

edit
AConstrained return Boolean

Ada Programming/Attributes/'Copy Sign

edit

 
Ada. Time-tested, safe and secure.


function S'Copy_Sign (Value, Sign : T)
  return T

Description

edit

S'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

edit
X : Float :=  1.5;
Y : Float := -1.0;
Z : Float :=  1.0;
 
pragma Assert (Float'Copy_Sign ( X, Y) = -1.5);   -- OK
pragma Assert (Float'Copy_Sign ( X, Z) =  1.5);   -- OK
pragma Assert (Float'Copy_Sign (-X, Z) =  1.5);   -- OK
pragma Assert (Float'Copy_Sign ( Y, Z) = -1.0);   -- Wrong

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Count

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
protected type My_Protected_Type is
  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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Default Bit Order

edit

Description

edit

Standard'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

edit

Description

edit

Standard'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

edit

Description

edit

S'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

edit
SDefinite return Boolean

Ada Programming/Attributes/'Delta

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
type My_Fixed is delta 0.1 range 0.0 .. 100.0;

pragma Assert (My_Fixed'Delta = 0.1);  -- OK

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Denorm

edit

Description

edit

True 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

edit
SDenorm return Boolean

Ada Programming/Attributes/'Deref

edit

Description

edit

The 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

edit

Description

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

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
type My_Float is digits 10 range 0.0 .. 100.0;
... 
pragma Assert (My_Float'Digits = 10);  -- OK

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Elab Body

edit

Description

edit

This 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

edit

This 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

edit

Description

edit

This 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

edit

Description

edit

The 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

edit

Description

edit

The 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

edit

Description

edit

The 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

 
Ada. Time-tested, safe and secure.


Description

edit

This 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

edit
type Enum_Type is (Enum1, Enum2, Enum3);
Enum_Val : Enum_Type  := Enum1;
pragma Assert (Enum_Type'Enum_Rep(Enum_Val) = 0);  -- OK

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada 2022 Overview

edit
edit

GNAT Reference Manual > Implementation Defined Attributes > Enum_Rep

Ada Programming/Attributes/'Enum Val

edit

This language feature has been introduced in Ada 2022.

Description

edit

Return 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

edit
type Enum_Type is (Enum1, Enum2, Enum3);
pragma Assert (Enum_Type'Enum_Val(0) = Enum1);  -- OK

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada 2022 Overview

edit
edit

GNAT Reference Manual > Implementation Defined Attributes > Enum_Val

Ada Programming/Attributes/'Epsilon

edit

Description

edit

The 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

edit

Description

edit

Returns 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

edit
SExponent (X:T) return universal_integer

Ada Programming/Attributes/'Extended Aft

edit

Description

edit

Returns 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

edit
T'EXTENDED_AFT(Base, Based)

Ada Programming/Attributes/'Extended Base

edit

Description

edit

For 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

edit
T'EXTENDED_BASE

Ada Programming/Attributes/'Extended Base

edit

Description

edit

For 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

edit
T'EXTENDED_BASE

Ada Programming/Attributes/'Extended Digits

edit

Description

edit

Returns 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

edit
T'EXTENDED_DIGITS(Base)

Ada Programming/Attributes/'Extended Fore

edit

Description

edit

Returns 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

edit
T'EXTENDED_FORE(Base, Based)

Ada Programming/Attributes/'Extended Image

edit

Description

edit

Returns 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

edit
T'EXTENDED_IMAGE(Item, Width, Base, Based, Space_If_Positive)

Ada Programming/Attributes/'Extended Value

edit

Description

edit

Returns 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

edit
T'EXTENDED_VALUE(Item)

Ada Programming/Attributes/'Extended Wide Image

edit

Description

edit

Returns 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

edit
T'EXTENDED_WIDE_IMAGE(Item, Width, Base, Based, Space_If_Positive)

Ada Programming/Attributes/'Extended Wide Value

edit

Description

edit

Returns 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

edit
T'EXTENDED_WIDE_VALUE(Item)

Ada Programming/Attributes/'Extended Wide Width

edit

Description

edit

Returns 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

edit
T'EXTENDED_WIDE_WIDTH(Base, Based, Space_If_Positive)

Ada Programming/Attributes/'Extended Width

edit

Description

edit

Returns 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

edit
T'EXTENDED_WIDTH(Base, Based, Space_If_Positive)

Ada Programming/Attributes/'External Tag

edit

Description

edit

An 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

edit
SExternal_Tag return String

Ada Programming/Attributes/'Fast Math

edit

Description

edit

Standard'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

edit

Description

edit

The 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

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
type My_Enum is (Enum1, Enum2, Enum3);
type My_Int  is range -1 .. 5;
... 
pragma Assert (My_Enum'First = Enum1);   -- OK
pragma Assert (My_Int'First  = -1);      -- OK
pragma Assert (My_Int'First  =  0);      -- Wrong!

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Fixed Value

edit

Description

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

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
X : Float := 1.5;
Y : Float := 1.0;
Z : Float := 1.999;
 
pragma Assert (Float'Floor (X) = 1.0);  -- OK
pragma Assert (Float'Floor (Y) = 1.0);  -- OK
pragma Assert (Float'Floor (Z) = 2.0);  -- Wrong

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Fore

edit

Description

edit

Minimum 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

edit
SFore return universal_integer

Ada Programming/Attributes/'Fraction

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'From Any

edit

Description

edit

This 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

edit

Description

edit

The 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

edit

Description

edit

The 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

edit

Description

edit

Returns 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

edit
XHas_Same_Storage (X2:any_type) return Boolean

Ada Programming/Attributes/'Has Tagged Values

edit

Description

edit

The 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

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
task My_Task;
task My_Other_Task;
...
if My_Task'Identity = My_Other_Task'Identity then
  -- Do something
end if;

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Image

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
type My_Enum is (Enum1, Enum2, Enum3); 
... 
pragma Assert (My_Enum'Image (Enum1) = "ENUM1");
pragma Assert (Enum1'Image = "ENUM1"); -- Ada 2022

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Img

edit

Description

edit

The 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

edit

Description

edit

Within a precondition or postcondition expression for entry family E, denotes the value of the entry index for the call of E.

Example

edit
EIndex return entry_index_subtype

Ada Programming/Attributes/'Initialized

edit

Description

edit

For the syntax and semantics of this attribute, see the SPARK 2014 Reference Manual, section 6.10.

Ada Programming/Attributes/'Input

edit

Description

edit

Reads 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

edit
SInput (Stream:access Ada.Streams.Root_Stream_TypeClass) return T

Ada Programming/Attributes/'Integer Value

edit

Description

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

edit

Description

edit

For 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

edit

The 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

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
type My_Enum is (Enum1, Enum2, Enum3);
type My_Int  is range -1 .. 5;
... 
pragma Assert (My_Enum'Last = Enum3);  -- OK
pragma Assert (My_Int'Last  = 5);      -- OK
pragma Assert (My_Int'Last  = 4);      -- Wrong!

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Leading Part

edit

Description

edit

The leading part of floating point value with number of radix digits given by second argument.

Example

edit
SLeading_Part (X:T;Radix_Digits:universal_integer) return T

Ada Programming/Attributes/'Length

edit

 
Ada. Time-tested, safe and secure.


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

edit

If you declare:

type My_Vector is array (1 .. 7) of Integer;
type My_Matrix is 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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Library Level

edit

Description

edit

P'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

edit

Description

edit
X'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

edit

Description

edit

Machine 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

edit
SMachine (X:T) return T

Ada Programming/Attributes/'Machine Emax

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
with Ada.Text_IO;

procedure Machine_Emax is

   package T_IO renames Ada.Text_IO;
   package I_IO is 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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Machine Emin

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
with Ada.Text_IO;

procedure Machine_Emin is

   package T_IO renames Ada.Text_IO;
   package I_IO is 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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Machine Mantissa

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
with Ada.Text_IO;

procedure Machine_Mantissa is

   package T_IO renames Ada.Text_IO;
   package I_IO is 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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Machine Overflows

edit

Description

edit

True 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

edit
SMachine_Overflows return Boolean

Ada Programming/Attributes/'Machine Radix

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
 with Ada.Text_IO;

 procedure Machine_Radix is

   package T_IO renames Ada.Text_IO;
   package I_IO is new  Ada.Text_IO.Integer_IO (Integer);

   type My_Fixed_Point_Type is delta 0.1 range -1.0 .. 1.0;
   type My_Decimal_Type is delta 0.01 digits 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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Machine Rounding

edit

Description

edit

Yields 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

edit
SMachine_Rounding (X:T) return T

Ada Programming/Attributes/'Machine Rounds

edit

Description

edit

True 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

edit
SMachine_Rounds return Boolean

Ada Programming/Attributes/'Machine Size

edit

Description

edit

This 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

edit

Description

edit

The 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

 
Ada. Time-tested, safe and secure.


Description

edit

'Max(X, Y) is a scalar type attribute. It returns the greater of the two parameters.

Example

edit
  type 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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Max Alignment For Allocation

edit

Description

edit

Maximum 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

edit
SMax_Alignment_For_Allocation return universal_integer

Ada Programming/Attributes/'Max Integer Size

edit

Description

edit

Standard'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

edit

Description

edit

Maximum 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

edit
SMax_Size_In_Storage_Elements return universal_integer

Ada Programming/Attributes/'Maximum Alignment

edit

Description

edit

Standard'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

edit

Description

edit

func'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

 
Ada. Time-tested, safe and secure.


Description

edit

'Min(X, Y) is a scalar type attribute. It returns the lesser of the two parameters.

Example

edit
type 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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Mod

edit

Description

edit

Will 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

edit
SMod (X:T) return S

Ada Programming/Attributes/'Model

edit

Description

edit

Model number of floating point type.

If the Numerics Annex is not supported, the meaning of this attribute is implementation defined.

Example

edit
SModel (X:T) return T

Ada Programming/Attributes/'Model Emin

edit

Description

edit

Model 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

edit
SModel_Emin return universal_integer

Ada Programming/Attributes/'Model Epsilon

edit

Description

edit

Absolute 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

edit
SModel_Epsilon return universal_real

Ada Programming/Attributes/'Model Mantissa

edit

Description

edit

Model 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

edit
SModel_Mantissa return universal_integer

Ada Programming/Attributes/'Model Small

edit

Description

edit

Smallest 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

edit
SModel_Small return universal_real

Ada Programming/Attributes/'Modulus

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'Modulus is an Ada attribute where X is any modular type. This returns the modulus of X.

Example

edit
type Unsigned_Byte is mod 2**8;
type Unsigned_Word is mod 2**16;
 
pragma Assert (Unsigned_Byte'Modulus = 256);  -- Ok
pragma Assert (Unsigned_Word'Modulus = 65536);  -- Ok

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Null Parameter

edit

Description

edit

A 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

edit

Description

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

edit

Description

edit

The 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

edit
XOld return T

Ada Programming/Attributes/'Output

edit

Description

edit

Writes the value of X to Stream, including any bounds or discriminants.

Example

edit
SOutput (Stream:access Ada.Streams.Root_Stream_TypeClass;X)

Ada Programming/Attributes/'Overlaps Storage

edit

Description

edit

Returns 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

edit
XOverlaps_Storage (X2) return Boolean

Ada Programming/Attributes/'Parallel Reduce

edit

Description

edit

Reduction 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

edit
XParallel_Reduce (Reducer,Initial_Value)

Ada Programming/Attributes/'Partition ID

edit

Description

edit

Identifies 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

edit
DPartition_ID return universal_integer

Ada Programming/Attributes/'Passed By Reference

edit

Description

edit

typ'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

edit

Description

edit

X'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

 
Ada. Time-tested, safe and secure.


Description

edit

The '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

edit
I: Integer := -30;

pragma Assert (Integer'Pos(I) = -30);  -- of type universal_integer

type My_Enum is  (Enum1, Enum2, Enum3);
for  My_Enum use (Enum1 => 2, Enum2 => 4, Enum3 => 6);
...
pragma Assert (My_Enum'Pos(Enum1) = 2);  -- Wrong, 2 is the internal representation, not the position
pragma Assert (My_Enum'Pos(Enum1) = 0);  -- Right
pragma Assert (My_Enum'Pos(Enum3) = 2);

subtype My_Enum_Sub is My_Enum range Enum1 .. Enum2;

pragma Assert (My_Enum_Sub'Pos (Enum3) = 2);  -- Enum3 does not belong to My_Enum_Sub

Another example without representation clause:

  type Color is  (Red, Blue, White);
  Object : Color := White;
begin 
  Put (Color'Pos (Object)); -- prints 2, position of White.
...

See also

edit

The 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

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Position

edit

 
Ada. Time-tested, safe and secure.


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 Representation Clauses.

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Pred

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
type My_Enum is (Enum1, Enum2, Enum3);
...
pragma Assert (My_Enum'Pred (Enum2) = Enum1); -- OK
pragma Assert (My_Enum'Pred (Enum1) = Enum3); -- Wrong

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Preelaborable Initialization

edit

Description

edit

Returns whether the type of S has preelaborable initialization.

Description

edit
SPreelaborable_Initialization return Boolean

Ada Programming/Attributes/'Preelaborate Initialization

edit

Description

edit

Returns 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

edit
SPreelaborable_Initialization return Boolean

Ada Programming/Attributes/'Priority

edit

Description

edit

Returns 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

edit
PPriority return System.Any_Priority

Ada Programming/Attributes/'Put Image

edit

Description

edit

Writes an image of the value of X.

Example

edit
SPut_Image (Buffer:Ada.Strings.Text_Buffers.Root_Buffer_TypeClass;X)

Ada Programming/Attributes/'Range

edit

 
Ada. Time-tested, safe and secure.


Description

edit

The 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

edit
type T is range 1..10;  --  T'Range is equal to T

type A is array (T) of S;                  --  these three     A'Range is the same as T
type A is array (T'Range) of S;            --  declarations
type A is array (T'First .. T'Last ) of S; --  are equivalent

type B is array (T range <>) of S;  --  B'Range is illegal (B is unconstrained)
subtype SB is B (2 .. 5);           --  SB'Range is the same as 2 .. 5

type M is 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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Range Length

edit

Description

edit

typ'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

edit

Description

edit

Reads the value of X from Stream.

Example

edit
SRead (Stream:access Ada.Streams.Root_Stream_TypeClass;X:out T)

Ada Programming/Attributes/'Reduce

edit

Description

edit

This attribute represents a reduction expression, and is in the form of a reduction_attribute_reference.

Example

edit
X|VReduce(Reducer, Initial_Value)

Ada Programming/Attributes/'Ref

edit

Description

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

edit

The 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)

edit

The 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

edit

In 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 ADDRESSREF (integer_value)
--to use unsigned addresses
for VECTOR use at SYSTEM.ADDRESSREF(16#808000d0#);
TOP_OF_MEMORY : SYSTEM.ADDRESS := SYSTEM.ADDRESSREF(16#FFFFFFFF#);

Ada Programming/Attributes/'Relative Deadline

edit

Description

edit

Relative 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

edit
PRelative_Deadline return Ada.Real_Time.Time_Span

Ada Programming/Attributes/'Remainder

edit

Description

edit

X'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

edit
type 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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Restriction Set

edit

Description

edit

This 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

edit

Description

edit

Within 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

edit
FResult return X

Ada Programming/Attributes/'Round

edit

Description

edit

Fixed-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

edit
FRound (X) return S

Ada Programming/Attributes/'Rounding

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
W : Float := -1.5;
X : Float :=  1.5;
Y : Float :=  1.0;
Z : Float :=  1.999;
...
pragma Assert (Float'Rounding(W) = -2.0); -- OK 
pragma Assert (Float'Rounding(X) =  2.0); -- OK
pragma Assert (Float'Rounding(Y) =  1.0); -- OK
pragma Assert (Float'Rounding(Z) =  2.0); -- OK
pragma Assert (Float'Rounding(W) = -1.0); -- Wrong
pragma Assert (Float'Rounding(X) =  1.0); -- Wrong

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Safe Emax

edit

Description

edit

The 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

edit

Description

edit

Returns 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

edit
SSafe_First return universal_real

Ada Programming/Attributes/'Safe Large

edit

Description

edit

The 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

edit

Description

edit

Returns 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

edit
SSafe_Last return universal_real

Ada Programming/Attributes/'Safe Small

edit

Description

edit

The 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

edit

Description

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 to position + (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

edit

Description

edit

Position 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

edit
SScale return universal_integer

Ada Programming/Attributes/'Scaling

edit

Description

edit

Scaling 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

edit
SScaling (X:T;Adjustment:universal_integer) return T

Ada Programming/Attributes/'Signed Zeros

edit

Description

edit

True 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

edit
SSigned_Zeros return Boolean

Ada Programming/Attributes/'Simple Storage Pool

edit

Description

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

 
Ada. Time-tested, safe and secure.


Description

edit

R'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

edit

This subtype allows a biased representation with only three bits because it comprises only eight values:

 type T is range 1000 .. 1007;
 for  T'Size use 3;

Without the size clause, T'Size would return 10 because 210-1 = 1023.

File: attributes_size.adb (view, plain text, download page, browse all)
with Ada.Text_IO;

procedure Attributes_Size is

   package T_IO renames Ada.Text_IO;
   package I_IO is 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 byte
end 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 Bool is new Boolean; 
for Bool'Size use Interfaces.C.int'Size;

Incorrect usages

edit

A 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

edit

Wikibook

edit

Ada 83 Reference Manual

edit

Ada 95 Reference Manual

edit

Ada 2005 Reference Manual

edit

Ada 2012 Reference Manual

edit

Ada Programming/Attributes/'Size:3

edit

A 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

edit

Description

edit

Small 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

edit
SSmall return universal_real

Ada Programming/Attributes/'Small Denominator

edit

Description

edit

typ'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

edit

Description

edit

typ'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

edit

Description

edit

Returns 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

edit
SStorage_Pool return Root_Storage_PoolClass

Ada Programming/Attributes/'Storage Size

edit

Description

edit

Number 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

edit
SStorage_Size return universal_integer

Ada Programming/Attributes/'Storage Unit

edit

Description

edit

Standard'Storage_Unit (Standard is the only allowed prefix) provides the same value as System.Storage_Unit.

Ada Programming/Attributes/'Stream Size

edit

Description

edit

Number 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

edit
SStream_Size return universal_integer

Ada Programming/Attributes/'Stub Type

edit

Description

edit

The 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

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
type My_Enum is (Enum1, Enum2, Enum3);
...
pragma Assert (My_Enum'Succ(Enum2) = Enum3);   -- OK
pragma Assert (My_Enum'Succ(Enum3) = Enum1);   -- Wrong

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'System Allocator Alignment

edit

Description

edit

Standard'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

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
Ref : My_Tagged_Type_Reference;
...
if Ref.all in My_Tagged_Type'Class then
  -- The object pointed at by Ref is in class hierarchy that is rooted at My_Tagged_Type.
  if Ref.all'Tag = My_Tagged_Type'Tag then
    -- 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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Target Name

edit

Description

edit

Standard'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

edit

Description

edit

For 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

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'To Address

edit

 
Ada. Time-tested, safe and secure.


Description

edit

System'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

edit

Using 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

edit

Wikibook

edit

GNAT Reference Manual

edit

Ada Programming/Attributes/'To Any

edit

Description

edit

This internal attribute is used for the generation of remote subprogram stubs in the context of the Distributed Systems Annex.

Ada Programming/Attributes/'Truncation

edit

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
X : Float :=  1.5;
Y : Float :=  1.0;
Z : Float := -1.999;
 
pragma Assert (Float'Truncation(X) =  1.0);  -- Ok
pragma Assert (Float'Truncation(Y) =  1.0);  -- Ok
pragma Assert (Float'Truncation(Z) = -1.0);  -- Ok
pragma Assert (Float'Truncation(Z) = -2.0);  -- Wrong

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'TypeCode

edit

Description

edit

This internal attribute is used for the generation of remote subprogram stubs in the context of the Distributed Systems Annex.

Ada Programming/Attributes/'Type Class

edit

Description

edit

typ'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

edit

Description

edit

The 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

 
Ada. Time-tested, safe and secure.


Description

edit

X'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

edit
X : Float := 1.5;
Y : Float := 1.0;
Z : Float := 1.999;
... 
pragma Assert(Float'Unbiased_Rounding(X) = 2.0);  -- OK
pragma Assert(Float'Unbiased_Rounding(Y) = 1.0);  -- OK
pragma Assert(Float'Unbiased_Rounding(Z) = 2.0);  -- OK
pragma Assert(Float'Unbiased_Rounding(X) = 1.0);  -- Wrong
...
X := 2.5;
pragma Assert(Float'Unbiased_Rounding(X) = 2.0 );  -- OK
pragma Assert(Float'Unbiased_Rounding(X) = 3.0 );  -- Wrong

See also

edit

Wikibook

edit

Ada Reference Manual

edit

Ada Programming/Attributes/'Unchecked Access

edit

Description

edit

Same 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

edit
XUnchecked_Access (X:T) return access type

Ada Programming/Attributes/'Unconstrained Array

edit

Description

edit

The 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

edit

Description

edit

The 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

edit

Description

edit

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

Ada Programming/Attributes/'Update