Non const static initialization, and program constructor/destructor code.
This crate provides lazy statics on all plateforms.
On unixes and windows lesser lazy statics are lazy during program startup phase
(before main
is called). Once main is called, those statics are all guaranteed to be
initialized and any access to them is as fast as any access to regular const initialized
statics. Benches sho that usual lazy statics, as those provided by std::lazy::*
or from
lazy_static crate, suffer from a 2ns access penalty.
Lesser lazy statics can optionaly be dropped at program destruction (after main exit but before the program stops).
Lesser lazy statics require the standard library and are enabled by default
crate features lazy
and lazy_drop
.
```rust use static_init::{dynamic};
static L1: Vec
On plateforms that support it (unixes, mac, windows), this crate provides dynamic statics: statics that are
initialized at program startup. This feature is no_std
.
```rust use static_init::{dynamic};
static D1: Vec
To prevent such hazardeous accesses, on unixes and window plateforms, a priority can be specified. Dynamic static initializations with higher priority are sequenced before dynamic static initializations with lower priority. Dynamic static initializations with the same priority are underterminately sequenced.
```rust use static_init::{dynamic};
// D2 initialization is sequenced before D1 initialization
static mut D1: Vec
static D2: Vec
Dynamic statics can be dropped at program destruction phase: they are dropped after main exit:
```rust use static_init::{dynamic};
// D2 initialization is sequenced before D1 initialization // D1 drop is sequenced before D2 drop.
static mut D1: Vec
static D2: Vec
On plateforms that support it (unixes, mac, windows), this crate provides a way to declare
constructors: a function called before main is called. This feature is no_std
.
```rust use static_init::{constructor};
//called before main
unsafe extern "C" fn some_init() {} ```
Constructors also support priorities. Sequencement rules applies also between constructor calls and between dynamic statics initialization and constructor calls.
destructors are called at program destruction. They also support priorities.
```rust use static_init::{constructor, destructor};
//called before some_init
unsafe extern "C" fn pre_init() {}
//called before main
unsafe extern "C" fn some_init() {}
//called after main
unsafe extern "C" fn first_destructor() {}
//called after first_destructor
unsafe extern "C" fn last_destructor() {} ```
If the feature debug_order
or debug_core
is enabled or when the crate is compiled with debug_assertions
,
attempts to access dynamic statics
that are uninitialized or whose initialization is
undeterminately sequenced with the access will cause a panic with a message specifying which
statics was tentatively accessed and how to change this dynamic static priority to fix this
issue.
Run cargo test
in this crate directory to see message examples.
All implementations of lazy statics may suffer from circular initialization dependencies. Those
circular dependencies will cause either a dead lock or an infinite loop. If the feature debug_lazy
or debug_order
is
enabled, atemp are made to detect those circular dependencies. In most case they will be detected.
std::lazy::Lazy
.