HP 3000 Manuals

Expressions [ HP Pascal/iX Reference Manual ] MPE/iX 5.0 Documentation


HP Pascal/iX Reference Manual

Expressions 

Type Coercion 

Pascal is very strict with respect to type checking.  In any operation
such as assignment, binary operations, passing parameter, or indexing,
relevant types must be compatible according to the HP Pascal rules of
compatible types.  Refer to "Type Compatibility"  for more
information.

Type coercion allows the user to selectively circumvent the normally
strong type checking.  The system programming extensions support several
forms of type coercion including ANYVAR, reference, and value.  ANYVAR
type coercion (using the formal parameter mechanism ANYVAR) is described
in this chapter under "Procedures and Functions" .

Reference type coercion consists of type coercion of an actual parameter
that is being passed to a reference formal parameter, or type coercing a
pointer to a different pointer type before a dereference.

Value type coercion consists of type coercion of a constant, variable,
function result, or expression to a different type.

The syntax for type coercion looks like the application of a function to
an expression, where the name of the function is the name of the target
type of the coercion.

Syntax 

     Expression:

[]
The expression being coerced may be a constant, variable, function result, or expression involving unary and binary operators. Syntactically, value type coercion is allowed: * In an expression. * On the right-hand side of an assignment statement. * On an actual parameter. By default, the compiler does not allow value type coercion. The compiler option TYPE_COERCION allows the user to enable a certain level of type coercion. There are three classes of type coercion based on the source and target types: ordinal, pointer, and free union type coercion. Ordinal and pointer type coercions are enabled by specifying the conversion level of type coercion. Instances of free union type coercion are enabled by specifying one of structural, representation, storage, or noncompatible type coercion. Ordinal Type Coercion. The ordinal types are viewed as different sets of names for the points on the integer number line. Given this view of ordinals, value type coercion of one ordinal type to another is simply a renaming operation. A type coercion expression is considered an ordinal coercion, if both the source expression (expression being coerced) and the target type (type to which the expression is being coerced) are any of the following types: * The predefined types integer, shortint, char, Boolean, and Bit16. * A user-declared enumerated type. * A user-declared subrange type. If the value of the source expression is out of range with respect to the allowed values of the target type, a subrange violation occurs. If range checking is on, this causes a run-time error. Example TYPE color_t = (red,orange,yellow,green,chartreuse,blue,indigo,violet); VAR i : integer; color : color_t; BEGIN ... color := chartreuse; i := integer( color ); { i has the value 4 } i := 3; color := color_t( i ); { color has the value green } i := 12; color := color_t( i ); { will cause a run-time error } ... END; Pointer Type Coercion. The pointer types are viewed as virtual addresses. Given this view, value type coercion from one pointer type to another is a mapping from one virtual address to another. On implementations that have alignment restrictions, it is an error if the alignment of the type that the source expression points to is smaller than the alignment of the type that the target type points to. If range checking is on, this causes a run-time error. See the HP Pascal/iX Programmer's Guide or the HP Pascal/HP-UX Programmer's Guide, depending on your implementation, for more information on alignment. Coercion from long-to-long and short-to-short pointers is a one-to-one mapping and involves no actual run-time conversion operations. Coercion from a short to a long pointer, in implementations where long pointers point to a wider class of objects than short pointers, may involve amending the value of the short pointer with additional address information that a long pointer requires. Coercion from a long to a short pointer, in implementations where long pointers point to a wider class of objects than short pointers, may involve truncating the value of the long pointer. If this occurs, the short pointer may not be able to address the original object pointed to by the long pointer because of the short pointer's limited addressing. This is an error. If range checking is on, this causes a run-time error. Example TYPE integer_pointer = ^ integer; real_pointer = ^ real; VAR ip : integer_pointer; rp : real_pointer; BEGIN ... ip := integer_pointer( rp ); ... END; Other Type Coercion. All type coercions that do not fall under the categories of ordinal and pointer type coercion can be viewed as the use of a free union, or tagless variant record, where the implementation overlays the record variants onto the same storage area. The model for value type coercion: type_1(expression) is equivalent to the function call: f_type_1(expression) where f_type_1 is defined as: FUNCTION f_type_1 (e: type_of_expression):type_1 ; VAR coerce_record : RECORD CASE Boolean OF true: ( source_variant : type_of_expression ); false: ( target_variant : type_1 ); END; BEGIN coerce_record.source_variant := e; f_type_1 := coerce_record.target_variant; END; The model for reference type coercion: target_type ( source ); is equivalent to: pointer_to_target_type ( addr ( source ) ) Whereas both ordinal and pointer type coercions may cause run-time errors if the source values are not representable in the target type, the free union form of type coercion never causes run-time errors. Depending upon the source and target types, free union type coercion consists of the following levels, listed in increasing order of freedom: * Structural * Representation * Storage * Noncompatible Structural. A type coercion expression is considered to be structural if the following are true: * The bitsizes of the source and target types are the same. * The alignment of the source and target types are the same. * The source and target types are compatible. * If the source and target are structured, then the corresponding component in the two structures obey the above three rules of bitsizes, alignment and compatibility. Structural type coercions are enabled by specifying 'STRUCTURAL' in the compiler option TYPE_COERCION. Structural type coercion is essentially a renaming of the components of a structure. Because the component types are guaranteed to be the same, the storage allocated for the source and target types is also the same, and reinterpreting the storage of the source as if it was of the target type will produce correct results. Example $TYPE_COERCION 'STRUCTURAL'$ ... TYPE source_t = RECORD i : integer; b : false..true; end; target_t = RECORD j : minint..maxint; c : Boolean; END; VAR source : source_t; target : target_t; ... BEGIN ... target := target_t(source); ... END; In the above example, the two record types are the same: their bitsizes are identical and their corresponding components are the same. Representation. A type coercion expression is considered to be representation type coercion if the bitsizes of the source and target types are the same. The internal structure of structured types for either the source or target does not matter. Representation type coercions are enabled by specifying 'REPRESENTATION' in the compiler option TYPE_COERCION. Example $STANDARD_LEVEL 'HP_MODCAL'$ PROCEDURE write_hex( n : integer ); TYPE nibble_array = PACKED ARRAY[0..7] OF 0..15; hex_digit_t = array [0..15] OF char; CONST hex_digit = hex_digit_t[ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' ]; VAR i : 0..7; BEGIN FOR i := 0 to 7 DO $PUSH, TYPE_COERCION 'REPRESENTATION'$ WRITE( hex_digit[ nibble_array( n )[i] ] ); $POP$ END; In the above example, the integer n is treated as an array of nibbles in order to extract each nibble sequentially and write out its value in hexadecimal. Since representation type coercion guarantees that the source and target types are identical in size, the compiler can guarantee that the entire integer is covered by the nibble array: there are no bits missed. Storage. A type coercion expression is considered to be storage type coercion, if the size of the storage allocated for the source is greater than the size of the storage allocated for the target type. Storage type coercion guarantees that no nonexistent memory is accessed and that no undefined bits are accessed. The following illustrates storage type coercion. The compiler guarantees that PROC never accesses a part of its formal parameter that is not actually part of the actual parameter. This is because the actual parameter is guaranteed to be larger than or the same size as the formal parameter. Example TYPE string_1 = STRING [255]; string_2 = STRING [80] VAR s1 : string_1; s2 : string_2; ... PROCEDURE PROC (VAR S : STRING_2); BEGIN ... END; ... $PUSH, TYPE_COERCION 'STORAGE'$ PROC ( string_2 (s1) ); $POP$ Noncompatible. Noncompatible type coercion permits anything to be coerced to anything. There is no guarantee that the accessed storage exists, nor that there is any accessible storage. Example FUNCTION non_protected_space: integer; TYPE big_index = 0..max_array_size-1; big_array = array[big_index] of integer; VAR idx : big_index; int : integer; BEGIN idx := 0; TRY WHILE (idx <= max_array_size-1) DO BEGIN $PUSH, TYPE_COERCION 'NONCOMPATIBLE'$ int := big_array( int )[idx]; $POP$ idx := idx + 1; end; non_protected_space := max_array_size-1; RECOVER non_protected_space := idx - 1; END; The previous example coerces an integer to an array of integers and keeps accessing farther out into the array until it cannot access any further. Note that this code assumes that: * TRY-RECOVER traps the error condition that occurs when the array access grows beyond the limits of the available space. * The value of the variable idx is updated correctly when execution is transferred to the RECOVER statement.


MPE/iX 5.0 Documentation