static_init!() { /* proc-macro */ }
Expand description
§Global non-lazy zero-cost statics without const fn
.
This macro is a safe* abstraction for initializing statics before main()
is called. The initializer is called before main()
and Drop
is called after main()
is finished.
§Syntax
Syntax
StaticItemWithInitializer :
static_init!
{ Visibility?static
Identifier:
Type (=
unsafe
static
Block );
}
§Undefined Behavior
*This macro may cause undefined behavior if:
- the initializer creates a new thread
- the initializer references other statics created with this macro
- the initializer references the static it is initializing (In violation of rust’s aliasing rules)
std::sync::mpmc
orstd::sync::mpsc
is used- See Use before and after main
For this reason, the unsafe keyword is required to declare initializers with this macro. In the future these scenarios will hopefully become compile errors, and the unsafe keyword will no longer be required.
§Examples
use static_initializer::static_init;
static_init! {
static TEST_STATIC: Vec<u8> = unsafe static { (0..15u8).collect() };
}
fn use_the_static() {
// Prints `Test vec: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]`
println!("Test vec: {:?}", TEST_STATIC.as_slice());
}
§Compatibility
This macro only works on certain operating systems due to the fact that it uses link sections to run code before main()
All major operating systems are supported, and more may be supported in the future.
wasm
is currently not supported.
§Under the hood
Internally this macro uses the #[link_section]
attribute in order to have initializers and deinitializers run before and after main()
On windows the link section used is .CRT$XCU<5 digit priority number>
for constructors and .CRT$XPTZ<5 digit priority number>
for destructors.
On macOS and ios, __DATA,__mod_init_func
and __DATA,__mod_term_func
are used.
On linux and other Unix-based operating systems, .init_array.<5 digit priority number>
and .fini_array.<5 digit priority number>
are used.
Note <5 digit priority number>
is replaced with a 5 digit base-10 formatted number ranging from 0
to u16::MAX
which represents the order in which the initializers are run. Priority is not currently used and is not supported on some operating systems.