Previous | Table of Contents | Next |
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
LOOPHOLE(e, T)
where e is an expression whose type is not an open array type and T is a type. It denotes es 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 es 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 es 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:
INC (VAR x: ADDRESS; n: INTEGER := 1) DEC (VAR x: ADDRESS; n: INTEGER := 1)
These are short for x := x + n and x := x - n, except that x is evaluated only once.
A DISPOSE statement has the form
DISPOSE (v)
where v is a writable designator whose type is not REFANY, ADDRESS, or NULL. If v is untraced, the statement frees the storage for vs 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 because the garbage collector probably will not trace them through u.
There are several fundamental interfaces that every Modula-3 implementation must provide:
Implementations are free to extend the required interfaces, provided they do not invalidate clients of the unextended interfaces.
Most Modula-3 implementations provide many other interfaces. A few that are recommended to other implementers, but not required are
The interfaces in this section are included verbatim as a Modula-3 program in a literate-programming style. Each call in the interface is followed by a description of the call.
See http://www.research.digital.com/SRC/modula-3/html or http://www.m3.org/ for other standard interfaces.
Previous | Table of Contents | Next |