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