Macro static_init

Source
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 or std::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.