There are some cases that no law can be framed to cover. --Aristotle
The features defined in this section can potentially cause unchecked runtime errors and are thus forbidden in safe interfaces and modules.
An unchecked type transfer operation has the form:
whereLOOPHOLE
(e, T)
e
is an expression whose type is not an open array type and
T
is a type. It denotes e
's bit pattern interpreted as a
variable or value of type T
. It is a designator if e
is, and is
writable if e
is. An unchecked runtime error can occur if e
's
bit pattern is not a legal T
, or if e
is a designator and some
legal bit pattern for T
is not legal for e
.
If T
is not an open array type, BITSIZE(e)
must equal
BITSIZE(T)
. If T
is an open array type, its element type must
not be an open array type, and e
's bit pattern is interpreted as an
array whose length is BITSIZE(e)
divided by BITSIZE(
the element
type of T)
. The division must come out even.
The following operations are primarily used for address arithmetic:
ADR
(VAR x: Any) : ADDRESS
infix+
(x: ADDRESS, y:INTEGER) : ADDRESS
infix-
(x: ADDRESS, y:INTEGER) : ADDRESS
infix-
(x,y: ADDRESS) : INTEGER
ADR(x)
is the address of the variable x
. The actual argument
must be a designator but need not be writable. The operations +
and
-
treat addresses as integers. The validity of the addresses produced
by these operations is implementation-dependent. For example, the address of
a variable in a local procedure frame is probably valid only for the duration
of the call. The address of the referent of a traced reference is probably
valid only as long as traced references prevent it from being collected (and
not even that long if the implementation uses a compacting collector).
In unsafe modules the INC
and DEC
statements apply to addresses
as well as ordinals:
These are short forINC
(VAR x: ADDRESS; n: INTEGER := 1)
DEC
(VAR x: ADDRESS; n: INTEGER := 1)
x := x + n
and x := x - n
, except that
x
is evaluated only once.
A DISPOSE
statement has the form:
whereDISPOSE
(v)
v
is a writable designator whose type is not REFANY
,
ADDRESS
, or NULL
. If v
is untraced, the statement frees
the storage for v
's referent and sets v
to NIL
. Freeing
storage to which active references remain is an unchecked runtime error. If
v
is traced, the statement is equivalent to v := NIL
. If
v
is NIL
, the statement is a no-op.
In unsafe interfaces and modules the definition of ``assignable'' for types is
extended: two reference types T
and U
are assignable if
T <: U
or U <: T
. The only effect of this change is to allow a
value of type ADDRESS
to be assigned to a variable of type
UNTRACED REF T
. It is an unchecked runtime error if the value does not
address a variable of type T
.
In unsafe interfaces and modules the type constructor UNTRACED REF T
is
allowed for traced as well as untraced T
, and the fields of untraced
objects can be traced. If u
is an untraced reference to a traced
variable t
, then the validity of the traced references in t
is
implementation-dependent, since the garbage collector probably will not trace
them through u
.
m3-support@elego.de