Non const static initialization, and program constructor/destructor code.
Lesser Lazy Statics
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
.
use ;
static L1: = vec!;
Dynamic statics: statics initialized at program startup
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
.
use ;
static D1: = unsafe ;
As can be seen above, the initializer expression of those statics must be an unsafe block. The reason is that during startup phase, accesses to dynamic statics may cause undefined behavior: dynamic statics may be in a zero initialized state.
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.
use ;
// D2 initialization is sequenced before D1 initialization
static mut D1: = unsafe ;
static D2: = unsafe ;
Dynamic statics can be dropped at program destruction phase: they are dropped after main exit:
use ;
// D2 initialization is sequenced before D1 initialization
// D1 drop is sequenced before D2 drop.
static mut D1: = unsafe ;
static D2: = unsafe ;
The priority act on drop in reverse order. Dynamic statics drops with a lower priority are sequenced before dynamic statics drops with higher priority.
Constructor and Destructor
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
.
use ;
//called before main
unsafe extern "C"
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.
use ;
//called before some_init
unsafe extern "C"
//called before main
unsafe extern "C"
//called after main
unsafe extern "C"
//called after first_destructor
unsafe extern "C"
Debuging initialization order
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.
Comparisons with other crates
Comparison of Lesser lazy statics with lazy_static or std::lazy::Lazy
.
- lazy_static only provides const statics;
- there are no cyclic initialization detection;
- Each access to lazy_static statics costs 2ns;
- syntax is more verbose.
dynamic statics with ctor
- ctor only provides const statics;
- ctor does not provide priorities;
- ctor unsafety is unsound;
- ctor does not support mutable statics;
- ctor does not provide a way to detect access to uninitialized data.