Undefined Behavior

Undefined behavior, often abbreviated UB, is the result of a violated assumption of the compiler or optimizer. Safe Rust is completely free of undefined behavior unless there are bugs in the dependencies, but unsafe code can cause UB if used incorrectly.

Example
This example uses the unsafe function to convert the integer   to a. The problem is that Rust assumes that any  is either   (represented as  ) or   (represented as  ). This means that  is in an invalid state – it is neither   nor.

This means that the compiler is free to assume that the code will never run and therefore can make certain optimizations, which can have drastic consequences in other parts of the code. This series of articles explains the impacts of UB; it focuses on C but the points also apply to Rust.

Sources of Undefined Behavior
This is an incomplete lists of things that can cause undefined behavior:

Invalid state
Many types only allow certain values. For example,  can only be   or. References must not be NULL. Enums can only have specific values as well. When transmuting types, values in an invalid state can be created.

Reading uninitialized memory
This can happen when using the deprecated function or  incorrectly.

Use after free
This occurs when you attempt to use a value whose destructor has already been run. This can happen when a transmuted value has the wrong lifetime.

Double free
This occurs when a value's destructor is run twice. This can happen when transmuting a borrowed value to an owned value. You should never do that.

Data race
This can happen when transmuting a shared reference to an exclusive reference. You should never do that.

Index out of bounds
Rust will usually prevent this and panic, but if an unsafe function such as is used, it can cause UB.

Wrong layout
When transmuting between values with incompatible memory layouts, UB can arise.