17 Unsafe Operations (original) (raw)

17 Unsafe Operations🔗

All functions and forms provided by racket/base andracket check their arguments to ensure that the arguments conform to contracts and other constraints. For example,vector-ref checks its arguments to ensure that the first argument is a vector, that the second argument is an exact integer, and that the second argument is between 0 and one less than the vector’s length, inclusive.

Functions provided by racket/unsafe/ops areunsafe. They have certain constraints, but the constraints are not checked, which allows the system to generate and execute faster code. If arguments violate an unsafe function’s constraints, the function’s behavior and result is unpredictable, and the entire system can crash or become corrupted.

All of the exported bindings of racket/unsafe/ops are protected in the sense of protect-out, so access to unsafe operations can be prevented by adjusting the code inspector (seeCode Inspectors).

17.1 Unsafe Numeric Operations🔗

Changed in version 7.0.0.13 of package base: Allow zero or more arguments for unsafe-fx+ and unsafe-fx*and allow one or more arguments for unsafe-fx-.

Changed in version 7.0.0.13 of package base: Allow zero or more arguments forunsafe-fxand, unsafe-fxior, and unsafe-fxxor.
Changed in version 8.8.0.5: Added unsafe-fxrshift/logical.

Added in version 8.5.0.6 of package base.

Added in version 7.9.0.6 of package base.

Changed in version 7.0.0.13 of package base: Allow one or more argument, instead of allowing just two.

Changed in version 7.0.0.13 of package base: Allow zero or more arguments for unsafe-fl+ and unsafe-fl*and one or more arguments for unsafe-fl- and unsafe-fl/.

Changed in version 7.0.0.13 of package base: Allow one or more argument, instead of allowing just two.

For flonums: Unchecked (potentially) versions offlround, flfloor, flceiling, andfltruncate. Currently, these bindings are simply aliases for the corresponding safe bindings.

Added in version 7.8.0.7 of package base.

For flonums: Unchecked (potentially) versions offlsin, flcos, fltan, flasin,flacos, flatan, fllog, flexp,flsqrt, and flexpt. Currently, some of these bindings are simply aliases for the corresponding safe bindings.

Changed in version 7.7.0.8 of package base: Changed unsafe-fl->fx to truncate.

17.2 Unsafe Character Operations🔗

Added in version 7.0.0.14 of package base.

17.3 Unsafe Compound-Data Operations🔗

Unsafe variant of cons that produces a pair that claims to be a list—without checking whether rest is a list.

Unsafe variants of list-ref and list-tail, wherepos must be a fixnum, and lst must start with at least (add1 pos) (for unsafe-list-ref) orpos (for unsafe-list-tail) pairs.

As their oxymoronic names should suggest, there is no generally correct way to use these functions. They may be useful nevertheless, as a last resort, in settings where pairs are used in a constrained way and when making correct assumptions about Racket’s implementation (including limits on the compiler’s optimizations).

Some pitfalls of using unsafe-set-immutable-car! andunsafe-set-immutable-cdr!:

Added in version 7.9.0.18 of package base.

Unsafe versions of unbox and set-box!, where thebox* variants can be faster but do not work onimpersonators.

A vector’s size can never be larger than a fixnum, so evenvector-length always returns a fixnum.

Changed in version 6.11.0.2 of package base: Added unsafe-vector*-cas!.
Changed in version 8.11.1.9: Added unsafe-vector-copy, unsafe-vector*-copy,unsafe-vector-set/copy, unsafe-vector*-set/copy,unsafe-vector-append, and unsafe-vector*-append.

Similar to vector->immutable-vector, but potentially destroysv and reuses it space, so v must not be used after calling unsafe-vector*->immutable-vector!.

Added in version 7.7.0.6 of package base.

Unsafe versions of string-length, string-ref, andstring-set!. The unsafe-string-ref procedure can be used only when the result will be a Latin-1 character. A string’s size can never be larger than a fixnum (so even string-lengthalways returns a fixnum).

Similar to string->immutable-string, but potentially destroysstr and reuses it space, so str must not be used after calling unsafe-string->immutable-string!.

Added in version 7.7.0.6 of package base.

Changed in version 7.5.0.15 of package base: Added unsafe-bytes-copy!.

Similar to bytes->immutable-bytes, but potentially destroysbstr and reuses it space, so bstr must not be used after calling unsafe-bytes->immutable-bytes!.

Added in version 7.7.0.6 of package base.

Added in version 8.5.0.7 of package base.

Unsafe field access and update for an instance of a structure type, where the struct* variants can be faster but do not work on impersonators. The index k must be between 0 (inclusive) and the number of fields in the structure (exclusive). In the case ofunsafe-struct-set!, unsafe-struct*-set!, and unsafe-struct*-cas!, the field must be mutable. The unsafe-struct*-cas! operation is analogous to box-cas! to perform an atomic compare-and-set.

Changed in version 6.11.0.2 of package base: Added unsafe-struct*-cas!.

Similar to struct-info, but without an inspector check, returning only the first result, and without support forimpersonators.

Added in version 8.8.0.3 of package base.

Each unsafe ...-first and ...-next procedure may return, instead of a number index, an internal representation of a view into the hash structure, enabling faster iteration. The result of these ...-first and ...-next functions should be given aspos to the corresponding unsafe accessor functions.

If the pos provided to an accessor function for a mutablehash was formerly a valid hash index but is no longer a valid hash index for hash, and ifbad-index-v is not provided, then theexn:fail:contract exception is raised. No behavior is specified for apos that was never a valid hash index forhash. Note that bad-index-v argument is technically not useful for the unsafe-immutable-hash-iterate- functions, since an index cannot become invalid for an immutable hash.

Added in version 6.4.0.6 of package base.
Changed in version 7.0.0.10: Added the optional bad-index-v argument.
Changed in version 8.0.0.10: Added ephemeron variants.

Unsafe version of srcloc.

Added in version 7.2.0.10 of package base.

17.4 Unsafe Extflonum Operations🔗

Unchecked (potentially) versions of extflsin,extflcos, extfltan, extflasin,extflacos, extflatan, extfllog,extflexp, extflsqrt, andextflexpt. Currently, some of these bindings are simply aliases for the corresponding safe bindings.

Changed in version 7.7.0.8 of package base: Changed unsafe-fl->fx to truncate.

17.5 Unsafe Impersonators and Chaperones🔗

Like impersonate-procedure, but assumes thatreplacement-proc calls proc itself. When the result of unsafe-impersonate-procedure is applied to arguments, the arguments are passed on to replacement-proc directly, ignoring proc. At the same time, impersonator-of?reports #t when given the result ofunsafe-impersonate-procedure and proc.

If proc is itself an impersonator that is derived fromimpersonate-procedure* or chaperone-procedure*, beware that replacement-proc will not be able to call it correctly. Specifically, the impersonator produced byunsafe-impersonate-procedure will not get passed to a wrapper procedure that was supplied toimpersonate-procedure* or chaperone-procedure* to generate proc.

Finally, unlike impersonate-procedure,unsafe-impersonate-procedure does not specially handleimpersonator-prop:application-mark as a prop.

The unsafety of unsafe-impersonate-procedure is limited to the above differences from impersonate-procedure. The contracts on the arguments of unsafe-impersonate-procedure are checked when the arguments are supplied.

is equivalent to

Similarly, with the same assumptions about f, the following two procedures wrap-f1 andwrap-f2 are almost equivalent; they differ only in the error message produced when their arguments are functions that return multiple values (and that they update different global variables). The version using unsafe-impersonate-procedurewill signal an error in the let expression about multiple return values, whereas the one using impersonate-procedure signals an error from impersonate-procedure about multiple return values.

Added in version 6.4.0.4 of package base.

Like unsafe-impersonate-procedure, but creates a chaperone. Since wrapper-proc will be called in lieu of proc,wrapper-proc is assumed to return a chaperone of the value thatproc would return.

Added in version 6.4.0.4 of package base.

Like impersonate-vector, but instead of going through interposition procedures, all accesses to the impersonator are dispatched to replacement-vec.

The result of unsafe-impersonate-vector is an impersonator of vec.

Added in version 6.9.0.2 of package base.

Like unsafe-impersonate-vector, but the result of unsafe-chaperone-vector is a chaperone of vec.

Added in version 6.9.0.2 of package base.

17.6 Unsafe Assertions🔗

Like assert-unreachable, but the contract ofunsafe-assert-unreachable is never satisfied, and the “unsafe” implication is that anything at all can happen if a call tounsafe-assert-unreachable is reached.

The compiler may take advantage of its liberty to pick convenient or efficient behavior in place of a call tounsafe-assert-unreachable. For example, the expression

may be compiled to code equivalent to

(lambda (x) (unsafe-car x))

because choosing to make (unsafe-assert-unreachable) behave the same as (unsafe-car x) makes both branches of theif the same, and then pair? test can be eliminated.

Added in version 8.0.0.11 of package base.

17.7 Unsafe Undefined🔗

The bindings documented in this section are provided by the racket/unsafe/undefined library, not racket/base or racket.

The constant unsafe-undefined is used internally as a placeholder value. For example, it is used by letrec as a value for a variable that has not yet been assigned a value. Unlike the undefined value exported by racket/undefined, however, the unsafe-undefined value should not leak as the result of a safe expression, and it should not be passed as an optional argument to a procedure (because it may count as “no value provided”). Expression results that potentially produce unsafe-undefined can be guarded bycheck-not-unsafe-undefined, so that an exception can be raised instead of producing an undefined value.

The unsafe-undefined value is always eq? to itself.

Added in version 6.0.1.2 of package base.
Changed in version 6.90.0.29: Procedures with optional arguments sometimes use the unsafe-undefinedvalue internally to mean “no argument supplied.”

The unsafe “undefined” constant.

See above for important constraints on the use of unsafe-undefined.

Checks whether v is unsafe-undefined, and raisesexn:fail:contract:variable in that case with an error message along the lines of “sym: undefined; use before initialization.” If v is not unsafe-undefined, then v is returned.

The same as check-not-unsafe-undefined, except that the error message (if any) is along the lines of “sym: undefined; assignment before initialization.”

Chaperones v if it is a structure (as viewed through someinspector). Every access of a field in the structure is checked to prevent returning unsafe-undefined. Similarly, every assignment to a field in the structure is checked (unless the check disabled as described below) to prevent assignment of a field whose current value is unsafe-undefined.

When a field access would otherwise produce unsafe-undefinedor when a field assignment would replace unsafe-undefined, theexn:fail:contract exception is raised.

The chaperone’s field-assignment check is disabled whenever(continuation-mark-set-first #f prop:chaperone-unsafe-undefined) returns unsafe-undefined. Thus, a field-initializing assignment—one that is intended to replace theunsafe-undefined value of a field—should be wrapped with(with-continuation-mark prop:chaperone-unsafe-undefined unsafe-undefined ....).

The property value should be a list of symbols used as field names, but the list should be in reverse order of the structure’s fields. When a field access or assignment would produce or replaceunsafe-undefined, the exn:fail:contract:variableexception is raised if a field name is provided by the structure property’s value, otherwise the exn:fail:contract exception is raised.