Function read_volatile

pub const unsafe fn read_volatile<T>(src: *const T) -> T

Performs a volatile read of the value from src without moving it.

Volatile operations are intended to act on I/O memory. As such, they are considered externally observable events (just like syscalls, but less opaque), and are guaranteed to not be elided or reordered by the compiler across other externally observable events. With this in mind, there are two cases of usage that need to be distinguished:

Note that volatile memory operations where T is a zero-sized type are noops and may be ignored.

When invoked during const evaluation, this behaves like a regular read. In particular, such reads must always follow the first of the two cases above.

Load splitting

Exactly which hardware loads are performed by this function is, in general, highly target-dependent.

For a simple scalar, such as when T is a thin pointer, this will typically be one load assuming your target supports a load of exactly that size and alignment.

For anything else, it will be split into multiple loads in some unspecified way. This can happen even for scalars: notably, on many targets loading a u128 will still need to be split, despite being "one" scalar. On many targets loading anything larger than a pointer will need to be split. On all current targets a load larger than 64 bytes will need to be split. Any load whose size is not a power of two will also almost certainly need to be split.

There is no stability guarantee on how that splitting happens. It may change at any point.

Safety

Like read, read_volatile creates a bitwise copy of T, regardless of whether T is Copy. If T is not Copy, using both the returned value and the value at *src can violate memory safety. However, storing non-Copy types in volatile memory is almost certainly incorrect.

Behavior is undefined if any of the following conditions are violated:

Note that even if T has size 0, the pointer must be properly aligned.

Examples

Basic usage:

let x = 12;
let y = &x as *const i32;

unsafe {
    assert_eq!(std::ptr::read_volatile(y), 12);
}