VIEW ( expr, type )
VIEW can be used to impose a "view" of a region of memory
as a different type. This view is type-safe -- it will not cause any
unchecked runtime errors. VIEW only incurs runtime
checks when the VIEW occurs.
The first argument, expr, must be a designator; that is,
it must describe a region of memory. The result of the
VIEW is a designator, and is writable if
expr is writable. Following are the restrictions
on the use of VIEW in more detail.
We make use the following definitions:
In our implementation, the set of non-representation-complete types consist of the following: REF, object, procedure, opaque REF, enum, subrange, set, float.
VIEW would be legal whenever the type of
expr --- call it T is
representation-equivalent to type. Our implementation is
simpler than this, and allows a VIEW under one of the
following conditions:
expr is representation-equivalent to
type. The following VIEW is legal:
VAR x: RECORD a, b: INTEGER := 3; END; BEGIN VIEW (x, RECORD a: INTEGER; END).a := 255; END;Our check for representation-equivalence is not much weaker than type equality. That is, A is representation-equivalent to B if A is equal to B, with the following weakening:
RECORD type, it can have extra fields at the
end that B does not have.
As a result, our implementation does not support the following
VIEW:
VAR x: RECORD a, b: INTEGER; END;
BEGIN
(* this is not supported by our implementation *)
VIEW (x, RECORD a: INTEGER; b: RECORD a: INTEGER; END; END).a := 255;
END;
expr is writable, then expr
must be representation-complete.
If this condition were not present, then the following would be legal:
VAR x: [0..254]; BEGIN VIEW (x, [0..255]) := 255; (* this is not legal! *) END;
This is a restriction made for the sake of simplicity, as we have
not seen any need for VIEWing multi-dimensional open arrays.
type must be representation-complete.
If this condition were not present, the following would be legal:
VAR x: [0..255] := 254; BEGIN WITH y = VIEW (x, [0..254]) DO x := 255; (* y is now 255, which is illegal! *) END; END;
type is an open array type, it cannot contain any
open arrays.
Without this restriction, there would be no means of determining the size of the resulting array.
expr and type. First, the size of
type
must be less than or equal to
that of expr. Second, the alignment of the
expr must satisfy the alignment of type.
If the sizes and alignments are known at compile-time,
the check is performed there; otherwise, there is a run-time
check.
TYPE T = RECORD
a: INTEGER;
b: INTEGER;
c: INTEGER;
END;
PROCEDURE p(x: ARRAY [0..10] OF INTEGER; y: ARRAY OF INTEGER;
z: ARRAY [0..100] OF [0..255]) =
BEGIN
WITH t = VIEW (x, T) DO
(* legal, no runtime check because sizes are known statically,
and alignments match *)
END
WITH t = VIEW (y, T) DO
(* legal, a runtime size check on the open array. alignments
match *)
END
WITH t = VIEW (z, T) DO
(* legal, a runtime alignment check, because z is only
aligned on an 8-bit boundary *)
END
END p;