Contents   Index   Search   Previous   Next


4.6 Type Conversions

1
   Explicit type conversions, both value conversions and view conversions, are allowed between closely related types as defined below. This clause also defines rules for value and view conversions to a particular subtype of a type, both explicit ones and those implicit in other constructs.

Syntax

2
type_conversion ::=
    subtype_mark(expression)
  | subtype_mark(name)
3
   The target subtype of a type_conversion is the subtype denoted by the subtype_mark. The operand of a type_conversion is the expression or name within the parentheses; its type is the operand type.
4
   One type is convertible to a second type if a type_conversion with the first type as operand type and the second type as target type is legal according to the rules of this clause. Two types are convertible if each is convertible to the other.
5/1
     A type_conversion whose operand is the name of an object is called a view conversion if both its target type and operand type are tagged, or if it appears as an actual parameter of mode out or in out; other type_conversions are called value conversions.

Name Resolution Rules

6
   The operand of a type_conversion is expected to be of any type.
7
   The operand of a view conversion is interpreted only as a name; the operand of a value conversion is interpreted as an expression.

Legality Rules

8
   If the target type is a numeric type, then the operand type shall be a numeric type.
9
   If the target type is an array type, then the operand type shall be an array type. Further:
10
11/1
12/1
12.1/1
13
    If the target type is a general access type, then the operand type shall be an access-to-object type. Further:
14
15
16
17
18
    If the target type is an access-to-subprogram type, then the operand type shall be an access-to-subprogram type. Further:
19
20
21
    If the target type is not included in any of the above four cases, there shall be a type that is an ancestor of both the target type and the operand type. Further, if the target type is tagged, then either:
22
23
24
    In a view conversion for an untagged type, the target type shall be convertible (back) to the operand type.

Static Semantics

25
    A type_conversion that is a value conversion denotes the value that is the result of converting the value of the operand to the target subtype.
26
    A type_conversion that is a view conversion denotes a view of the object denoted by the operand. This view is a variable of the target type if the operand denotes a variable; otherwise it is a constant of the target type.
27
    The nominal subtype of a type_conversion is its target subtype.

Dynamic Semantics

28
    For the evaluation of a type_conversion that is a value conversion, the operand is evaluated, and then the value of the operand is converted to a corresponding value of the target type, if any. If there is no value of the target type that corresponds to the operand value, Constraint_Error is raised; this can only happen on conversion to a modular type, and only when the operand value is outside the base range of the modular type. Additional rules follow:
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
    After conversion of the value to the target type, if the target subtype is constrained, a check is performed that the value satisfies this constraint.
52
    For the evaluation of a view conversion, the operand name is evaluated, and a new view of the object denoted by the operand is created, whose type is the target type; if the target type is composite, checks are performed as above for a value conversion.
53
    The properties of this new view are as follows:
54/1
55
56
57
    If an Accessibility_Check fails, Program_Error is raised. Any other check associated with a conversion raises Constraint_Error if it fails.
58
    Conversion to a type is the same as conversion to an unconstrained subtype of the type.
NOTES
59
20  In addition to explicit type_conversions, type conversions are performed implicitly in situations where the expected type and the actual type of a construct differ, as is permitted by the type resolution rules (see 8.6). For example, an integer literal is of the type universal_integer, and is implicitly converted when assigned to a target of some specific integer type. Similarly, an actual parameter of a specific tagged type is implicitly converted when the corresponding formal parameter is of a class-wide type.
60
21  Even when the expected and actual types are the same, implicit subtype conversions are performed to adjust the array bounds (if any) of an operand to match the desired target subtype, or to raise Constraint_Error if the (possibly adjusted) value does not satisfy the constraints of the target subtype.
61
A ramification of the overload resolution rules is that the operand of an (explicit) type_conversion cannot be the literal null, an allocator, an aggregate, a string_literal, a character_literal, or an attribute_reference for an Access or Unchecked_Access attribute. Similarly, such an expression enclosed by parentheses is not allowed. A qualified_expression (see 4.7) can be used instead of such a type_conversion.
62
22  The constraint of the target subtype has no effect for a type_conversion of an elementary type passed as an out parameter. Hence, it is recommended that the first subtype be specified as the target to minimize confusion (a similar recommendation applies to renaming and generic formal in out objects).

Examples

63
    Examples of numeric type conversion:
64
Real(2*J)      --  value is converted to floating point
Integer(1.6)   --  value is 2
Integer(-0.4)  --  value is 0
65
    Example of conversion between derived types:
66
type A_Form is new B_Form;
67
X : A_Form;
Y : B_Form;
68
X := A_Form(Y);
Y := B_Form(X);  --  the reverse conversion 
69
    Examples of conversions between array types:
70
type Sequence is array (Integer range <>) of Integer;
subtype Dozen is Sequence(1 .. 12);
Ledger : array(1 .. 100) of Integer;
71
Sequence(Ledger)            --  bounds are those of Ledger
Sequence(Ledger(31 .. 42))  --  bounds are 31 and 42
Dozen(Ledger(31 .. 42))     --  bounds are those of Dozen 

Contents   Index   Search   Previous   Next   Legal