Unsafety

Guideline: Undefined behavior shall not occur during the execution of a program gui_n4sX2E4G2qoX
status: draft
tags: undefined-behavior
category: required
decidability: undecidable
scope: system
release: -

This rule addresses all instances of undefined behavior not already covered by other guidelines.

Rationale: rat_xYF9mDPQRStx
status: draft
parent needs: gui_n4sX2E4G2qoX

Once an execution encounters undefined behavior it is impossible to reason about it anymore. Instances of undefined behavior can manifest in any kind of undesired behavior like crashes or silent memory corruption.

Non-Compliant Example: non_compl_ex_bkYi0Sb97r3N
status: draft
parent needs: gui_n4sX2E4G2qoX

Explanation of code example.

The only allowed representation of bool is either 0 or 1. Therefore, transmuting 3_u8 to bool violates its validity invariant and is undefined behavior.

fn example_function() -> bool {
    unsafe {
        std::transmute<bool>(3_u8)
    }
}

A necessary condition to read the value behind a pointer is that it points to a valid allocation. This is never the case for a null pointer, therefore reading it is undefined behavior. See the safety precondition of std::ptr::read.

fn example_function() {
    unsafe {
        std::ptr::read(std::ptr::null());
    }
}
Compliant Example: compl_ex_mt8h0T3BtONt
status: draft
parent needs: gui_n4sX2E4G2qoX

Since 0_u8 is defined to represent the false value of bool, this example is free of undefined behavior.

fn example_function() -> bool {
    unsafe {
        std::transmute<bool>(0_u8);
    }
}

ptr points to a valid, aligned and properly initialized allocation. Therefore, it satisfies all safety preconditions of std::ptr::read and can be read without undefined behavior.

fn example_function() {
    let ptr = Box::new(42).into_raw();
    unsafe {
        std::ptr::read(ptr);
    }
}