### 17Unsafe Operations

 (require racket/unsafe/ops) package: base

All functions and forms provided by racket/base and racket 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 are unsafe. 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 (see Code Inspectors).

#### 17.1Unsafe Numeric Operations

 procedure(unsafe-fx+ a b) → fixnum? a : fixnum? b : fixnum?
 procedure(unsafe-fx- a b) → fixnum? a : fixnum? b : fixnum?
 procedure(unsafe-fx* a b) → fixnum? a : fixnum? b : fixnum?
 procedure a : fixnum? b : fixnum?
 procedure a : fixnum? b : fixnum?
 procedure a : fixnum? b : fixnum?
 procedure a : fixnum?
For fixnums: Like +, -, *, quotient, remainder, modulo, and abs, but constrained to consume fixnums and produce a fixnum result. The mathematical operation on a and b must be representable as a fixnum. In the case of unsafe-fxquotient, unsafe-fxremainder, and unsafe-fxmodulo, b must not be 0.

 procedure(unsafe-fxand a b) → fixnum? a : fixnum? b : fixnum?
 procedure(unsafe-fxior a b) → fixnum? a : fixnum? b : fixnum?
 procedure(unsafe-fxxor a b) → fixnum? a : fixnum? b : fixnum?
 procedure a : fixnum?
 procedure a : fixnum? b : fixnum?
 procedure a : fixnum? b : fixnum?
For fixnums: Like bitwise-and, bitwise-ior, bitwise-xor, bitwise-not, and arithmetic-shift, but constrained to consume fixnums; the result is always a fixnum. The unsafe-fxlshift and unsafe-fxrshift operations correspond to arithmetic-shift, but require non-negative arguments; unsafe-fxlshift is a positive (i.e., left) shift, and unsafe-fxrshift is a negative (i.e., right) shift, where the number of bits to shift must be less than the number of bits used to represent a fixnum. In the case of unsafe-fxlshift, bits in the result beyond the number of bits used to represent a fixnum are effectively replaced with a copy of the high bit.

 procedure(unsafe-fx= a b) → boolean? a : fixnum? b : fixnum?
 procedure(unsafe-fx< a b) → boolean? a : fixnum? b : fixnum?
 procedure(unsafe-fx> a b) → boolean? a : fixnum? b : fixnum?
 procedure(unsafe-fx<= a b) → boolean? a : fixnum? b : fixnum?
 procedure(unsafe-fx>= a b) → boolean? a : fixnum? b : fixnum?
 procedure(unsafe-fxmin a b) → fixnum? a : fixnum? b : fixnum?
 procedure(unsafe-fxmax a b) → fixnum? a : fixnum? b : fixnum?
For fixnums: Like =, <, >, <=, >=, min, and max, but constrained to consume fixnums.

 procedure(unsafe-fl+ a b) → flonum? a : flonum? b : flonum?
 procedure(unsafe-fl- a b) → flonum? a : flonum? b : flonum?
 procedure(unsafe-fl* a b) → flonum? a : flonum? b : flonum?
 procedure(unsafe-fl/ a b) → flonum? a : flonum? b : flonum?
 procedure a : flonum?
For flonums: Unchecked versions of fl+, fl-, fl*, fl/, and flabs.

 procedure(unsafe-fl= a b) → boolean? a : flonum? b : flonum?
 procedure(unsafe-fl< a b) → boolean? a : flonum? b : flonum?
 procedure(unsafe-fl> a b) → boolean? a : flonum? b : flonum?
 procedure(unsafe-fl<= a b) → boolean? a : flonum? b : flonum?
 procedure(unsafe-fl>= a b) → boolean? a : flonum? b : flonum?
 procedure(unsafe-flmin a b) → flonum? a : flonum? b : flonum?
 procedure(unsafe-flmax a b) → flonum? a : flonum? b : flonum?
For flonums: Unchecked versions of fl=, fl<, fl>, fl<=, fl>=, flmin, and flmax.

 procedure a : flonum?
 procedure a : flonum?
 procedure a : flonum?
 procedure a : flonum?
For flonums: Unchecked (potentially) versions of flround, flfloor, flceiling, and fltruncate. Currently, these bindings are simply aliases for the corresponding safe bindings.

 procedure a : flonum?
 procedure a : flonum?
 procedure a : flonum?
 procedure a : flonum?
 procedure a : flonum?
 procedure a : flonum?
 procedure a : flonum?
 procedure a : flonum?
 procedure a : flonum?
 procedure(unsafe-flexpt a b) → flonum? a : flonum? b : flonum?
For flonums: Unchecked (potentially) versions of flsin, flcos, fltan, flasin, flacos, flatan, fllog, flexp, flsqrt, and flexpt. Currently, some of these bindings are simply aliases for the corresponding safe bindings.

procedure

 (and/c complex? (lambda (c) (flonum? (real-part c))) (lambda (c) (flonum? (imag-part c))))
a : flonum?
b : flonum?

procedure

a :
 (and/c complex? (lambda (c) (flonum? (real-part c))) (lambda (c) (flonum? (imag-part c))))

procedure

a :
 (and/c complex? (lambda (c) (flonum? (real-part c))) (lambda (c) (flonum? (imag-part c))))
For flonums: Unchecked versions of make-flrectangular, flreal-part, and flimag-part.

 procedure a : fixnum?
 procedure a : flonum?
Unchecked conversion of a fixnum to an integer flonum and vice versa. These are similar to the safe bindings ->fl and fl->exact-integer, but further constrained to consume or produce a fixnum.

 procedure(unsafe-flrandom rand-gen) → (and flonum? (>/c 0) (
Unchecked version of flrandom.

#### 17.2Unsafe Data Extraction

 procedure(unsafe-car p) → any/c p : pair?
 procedure(unsafe-cdr p) → any/c p : pair?
 procedure(unsafe-mcar p) → any/c p : mpair?
 procedure(unsafe-mcdr p) → any/c p : mpair?
 procedure p : mpair? v : any/c
 procedure p : mpair? v : any/c
Unsafe variants of car, cdr, mcar, mcdr, set-mcar!, and set-mcdr!.

 procedure(unsafe-cons-list v rest) → (and/c pair? list?) v : any/c rest : list?
Unsafe variant of cons that produces a pair that claims to be a list—without checking whether rest is a list.

 procedure(unsafe-list-ref lst pos) → any/c lst : pair? pos : (and/c exact-nonnegative-integer? fixnum?)
 procedure(unsafe-list-tail lst pos) → any/c lst : any/c pos : (and/c exact-nonnegative-integer? fixnum?)
Unsafe variants of list-ref and list-tail, where pos must be a fixnum, and lst must start with at least (add1 pos) (for unsafe-list-ref) or pos (for unsafe-list-tail) pairs.

 procedure b : box?
 procedure(unsafe-set-box! b k) → void? b : box? k : fixnum?
 procedure v : (and/c box? (not/c impersonator?))
 procedure(unsafe-set-box*! v val) → void? v : (and/c box? (not/c impersonator?)) val : any/c
Unsafe versions of unbox and set-box!, where the box* variants can be faster but do not work on impersonators.

 procedure(unsafe-box*-cas! loc old new) → boolean? loc : box? old : any/c new : any/c
Unsafe version of box-cas!. Like unsafe-set-box*!, it does not work on impersonators.

 procedure v : vector?
 procedure v : vector? k : fixnum?
 procedure(unsafe-vector-set! v k val) → void? v : vector? k : fixnum? val : any/c
 procedure v : (and/c vector? (not/c impersonator?))
 procedure v : (and/c vector? (not/c impersonator?)) k : fixnum?
 procedure(unsafe-vector*-set! v k val) → void? v : (and/c vector? (not/c impersonator?)) k : fixnum? val : any/c
 procedure(unsafe-vector*-cas! v k old-val new-val) → boolean? v : (and/c vector? (not/c impersonator?)) k : fixnum? old-val : any/c new-val : any/c
Unsafe versions of vector-length, vector-ref, vector-set!, and vector-cas!, where the vector* variants can be faster but do not work on impersonators.

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

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

 procedure str : string?
 procedure(unsafe-string-ref str k) → (and/c char? (lambda (ch) (<= 0 (char->integer ch) 255))) str : string? k : fixnum?
 procedure(unsafe-string-set! str k ch) → void? str : (and/c string? (not/c immutable?)) k : fixnum? ch : char?
Unsafe versions of string-length, string-ref, and string-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-length always returns a fixnum).

 procedure(unsafe-bytes-length bstr) → fixnum? bstr : bytes?
 procedure(unsafe-bytes-ref bstr k) → byte? bstr : bytes? k : fixnum?
 procedure(unsafe-bytes-set! bstr k b) → void? bstr : (and/c bytes? (not/c immutable?)) k : fixnum? b : byte?
Unsafe versions of bytes-length, bytes-ref, and bytes-set!. A bytes’s size can never be larger than a fixnum (so even bytes-length always returns a fixnum).

 procedure v : fxvector?
 procedure v : fxvector? k : fixnum?
 procedure v : fxvector? k : fixnum? x : fixnum?
Unsafe versions of fxvector-length, fxvector-ref, and fxvector-set!. A fxvector’s size can never be larger than a fixnum (so even fxvector-length always returns a fixnum).

 procedure v : flvector?
 procedure v : flvector? k : fixnum?
 procedure v : flvector? k : fixnum? x : flonum?
Unsafe versions of flvector-length, flvector-ref, and flvector-set!. A flvector’s size can never be larger than a fixnum (so even flvector-length always returns a fixnum).

 procedure(unsafe-f64vector-ref vec k) → flonum? vec : f64vector? k : fixnum?
 procedure(unsafe-f64vector-set! vec k n) → void? vec : f64vector? k : fixnum? n : flonum?
Unsafe versions of f64vector-ref and f64vector-set!.

 procedure(unsafe-s16vector-ref vec k) → (integer-in -32768 32767) vec : s16vector? k : fixnum?
 procedure(unsafe-s16vector-set! vec k n) → void? vec : s16vector? k : fixnum? n : (integer-in -32768 32767)
Unsafe versions of s16vector-ref and s16vector-set!.

 procedure(unsafe-u16vector-ref vec k) → (integer-in 0 65535) vec : u16vector? k : fixnum?
 procedure(unsafe-u16vector-set! vec k n) → void? vec : u16vector? k : fixnum? n : (integer-in 0 65535)
Unsafe versions of u16vector-ref and u16vector-set!.

 procedure v : any/c k : fixnum?
 procedure(unsafe-struct-set! v k val) → void? v : any/c k : fixnum? val : any/c
 procedure v : (not/c impersonator?) k : fixnum?
 procedure(unsafe-struct*-set! v k val) → void? v : (not/c impersonator?) k : fixnum? val : any/c
 procedure(unsafe-struct*-cas! v k old-val new-val) → boolean? v : (not/c impersonator?) k : fixnum? old-val : any/c new-val : any/c
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 of unsafe-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!.

 procedure h : (and/c hash? (not/c immutable?) (not/c hash-weak?))
 procedure h : (and/c hash? (not/c immutable?) (not/c hash-weak?)) i : any/c
 procedure h : (and/c hash? (not/c immutable?) (not/c hash-weak?)) i : any/c
 procedure h : (and/c hash? (not/c immutable?) (not/c hash-weak?)) i : any/c

procedure

(unsafe-mutable-hash-iterate-key+value h i)
 any/c any/c
h : (and/c hash? (not/c immutable?) (not/c hash-weak?))
i : any/c
 procedure h : (and/c hash? (not/c immutable?) (not/c hash-weak?)) i : any/c
 procedure h : (and/c hash? immutable?)
 procedure h : (and/c hash? immutable?) i : any/c
 procedure h : (and/c hash? immutable?) i : any/c
 procedure h : (and/c hash? immutable?) i : any/c

procedure

(unsafe-immutable-hash-iterate-key+value h
i)
 any/c any/c
h : (and/c hash? immutable?)
i : any/c
 procedure h : (and/c hash? immutable?) i : any/c
 procedure h : (and/c hash? hash-weak?)
 procedure h : (and/c hash? hash-weak?) i : any/c
 procedure h : (and/c hash? hash-weak?) i : any/c
 procedure h : (and/c hash? hash-weak?) i : any/c

procedure

(unsafe-weak-hash-iterate-key+value h i)
 any/c any/c
h : (and/c hash? hash-weak?)
i : any/c
 procedure h : (and/c hash? hash-weak?) i : any/c
Unsafe versions of hash-iterate-key and similar ops. These operations support chaperones and impersonators.

Each unsafe -first and -next operation may not return a number index but rather an internal representation of a view into the hash structure, enabling faster iteration.

The result of these -first and -next] functions should be given to the corresponding unsafe accessor functions.

If the key or value at the position returned by the -first and -next ops becomes invalid (e.g., because of mutation or garbage collection), then the operations exn:fail:contract exception is raised.

Added in version 6.4.0.6 of package base.

#### 17.3Unsafe Extflonum Operations

 procedure a : extflonum? b : extflonum?
 procedure a : extflonum? b : extflonum?
 procedure a : extflonum? b : extflonum?
 procedure a : extflonum? b : extflonum?
 procedure a : extflonum?
Unchecked versions of extfl+, extfl-, extfl*, extfl/, and extflabs.

 procedure a : extflonum? b : extflonum?
 procedure a : extflonum? b : extflonum?
 procedure a : extflonum? b : extflonum?
 procedure a : extflonum? b : extflonum?
 procedure a : extflonum? b : extflonum?
 procedure a : extflonum? b : extflonum?
 procedure a : extflonum? b : extflonum?
Unchecked versions of extfl=, extfl<, extfl>, extfl<=, extfl>=, extflmin, and extflmax.

 procedure a : extflonum?
 procedure a : extflonum?
 procedure a : extflonum?
 procedure a : extflonum?
Unchecked (potentially) versions of extflround, extflfloor, extflceiling, and extfltruncate. Currently, these bindings are simply aliases for the corresponding safe bindings.

 procedure a : extflonum?
 procedure a : extflonum?
 procedure a : extflonum?
 procedure a : extflonum?
 procedure a : extflonum?
 procedure a : extflonum?
 procedure a : extflonum?
 procedure a : extflonum?
 procedure a : extflonum?
 procedure a : extflonum? b : extflonum?
Unchecked (potentially) versions of extflsin, extflcos, extfltan, extflasin, extflacos, extflatan, extfllog, extflexp, extflsqrt, and extflexpt. Currently, some of these bindings are simply aliases for the corresponding safe bindings.

 procedure a : fixnum?
 procedure a : extflonum?
Unchecked conversion of a fixnum to an integer extflonum and vice versa. These are similar to the safe bindings ->extfl and extfl->exact-integer, but further constrained to consume or produce a fixnum.

 procedure v : extflvector?
 procedure v : extflvector? k : fixnum?
 procedure v : extflvector? k : fixnum? x : extflonum?
Unchecked versions of extflvector-length, extflvector-ref, and extflvector-set!. A extflvector’s size can never be larger than a fixnum (so even extflvector-length always returns a fixnum).

#### 17.4Unsafe Impersonators and Chaperones

procedure

 (unsafe-impersonate-procedure proc replacement-proc prop prop-val ... ...)
(and/c procedure? impersonator?)
proc : procedure?
replacement-proc : procedure?
prop : impersonator-property?
prop-val : any
Like impersonate-procedure, but assumes that replacement-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 of unsafe-impersonate-procedure and proc.

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

Finally, unlike impersonate-procedure, unsafe-impersonate-procedure does not specially handle impersonator-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.

As an example, assuming that f accepts a single argument and is not derived from impersonate-procedure* or chaperone-procedure*, then
 (λ (f) (unsafe-impersonate-procedure f (λ (x) (if (number? x) (error 'no-numbers!) (f x)))))
is equivalent to
 (λ (f) (impersonate-procedure f (λ (x) (if (number? x) (error 'no-numbers!) x))))

Similarly, with the same assumptions about f, the following two procedures wrap-f1 and wrap-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-procedure will 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.
 (define log1-args '()) (define log1-results '()) (define wrap-f1 (λ (f) (impersonate-procedure f (λ (arg) (set! log1-args (cons arg log1-args)) (values (λ (res) (set! log1-results (cons res log1-results)) res) arg))))) (define log2-args '()) (define log2-results '()) (define wrap-f2 (λ (f) (unsafe-impersonate-procedure f (λ (arg) (set! log2-args (cons arg log2-args)) (let ([res (f arg)]) (set! log2-results (cons res log2-results)) res)))))

Added in version 6.4.0.4 of package base.

procedure

 (unsafe-chaperone-procedure proc wrapper-proc prop prop-val ... ...)
(and/c procedure? chaperone?)
proc : procedure?
wrapper-proc : procedure?
prop : impersonator-property?
prop-val : any
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 that proc would return.

Added in version 6.4.0.4 of package base.

procedure

 (unsafe-impersonate-vector vec replacement-vec prop prop-val ... ...)
(and/c vector? impersonator?)
vec : vector?
replacement-vec : (and/c vector? (not/c impersonator?))
prop : impersonator-property?
prop-val : any/c
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.

procedure

 (unsafe-chaperone-vector vec replacement-vec prop prop-val ... ...)
(and/c vector? chaperone?)
vec : vector?
replacement-vec : (and/c vector? (not/c impersonator?))
prop : impersonator-property?
prop-val : any/c
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.5Unsafe Undefined

 (require racket/unsafe/undefined) package: base
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. Expression results that potentially produce unsafe-undefined can be guarded by check-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.

 value
The unsafe “undefined” constant.

 procedure → (and/c any/c (not/c (one-of/c unsafe-undefined))) v : any/c sym : symbol?
Checks whether v is unsafe-undefined, and raises exn: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.

 procedure → (and/c any/c (not/c (one-of/c unsafe-undefined))) v : any/c sym : symbol?
The same as check-not-unsafe-undefined, except that the error message (if any) is along the lines of “sym: undefined; assignment before initialization.”

 procedure v : any/c
Chaperones v if it is a structure (as viewed through some inspector). 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-undefined or when a field assignment would replace unsafe-undefined, the exn: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 the unsafe-undefined value of a field—should be wrapped with (with-continuation-mark prop:chaperone-unsafe-undefined unsafe-undefined ....).

 value
A structure type property that causes a structure type’s constructor to produce a chaperone of an instance in the same way as chaperone-struct-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 replace unsafe-undefined, the exn:fail:contract:variable exception is raised if a field name is provided by the structure property’s value, otherwise the exn:fail:contract exception is raised.