Dynamic Security Check

In addition to security assurance provided by static types, Cangjie also attaches great importance to runtime security checks. For some scenarios where static types are not suitable, Cangjie provides security assurance via runtime checks.

Overflow Check

Unlike most common languages, Cangjie by default performs overflow checks on integer operations, rather than wrapping.

If contextual information is sufficient, integer overflows can be detected by static analysis during compilation, and the compiler will report an error. Otherwise, if there is not enough information for static analysis, an integer overflow check will be performed at runtime, and a runtime exception will be thrown if an overflow is detected.

With this mechanism, integer overflows can be detected in a timely manner in most cases, preventing business risks.

Runtime checks lead to extra computational overhead, but the computational overhead can be controlled at a relatively low level with optimizations by the Cangjie compiler.

In some sensitive scenarios, it can be better to accept numeric wrapping for the sake of performance. In such cases, an overflow policy can be manually specified to implement the wrapping behavior common to many other languages.

@OverflowWrapping
func test(x: Int8, y: Int8) { // If **x** is 127 and **y** is 3
    let z = x + y // **z** is -126
}

Array Out-of-Bounds Check

Similarly, for index accesses to Cangjie arrays, out-of-bounds checks are performed. If information of the context is sufficient, out-of-bounds index accesses can be detected by static analysis in the compiler, and a compilation error will be reported directly. If there is not enough information for static analysis, index access checks are performed at runtime, and a runtime exception is thrown if an overflow is detected.

func f(index: Int) {
    let a = [1, 2, 3]
    let b = a[-1] // An error is reported during compilation.
    let c = a[index] // A check is performed at runtime.
}