LICENSE LICENSE Documentation Crates.io Version

Module initialization termination function with priorities and (mutable) statics initialization with non const functions.

# Functionalities

[X] Code execution before or after main but after libc and rust runtime has been initialized.

[X] Mutable and const statics with non const initialization.

[X] Statics droppable after main exits.

[X] Zero cost access to statics.

[X] Priorities on elf plateforms (linux, bsd, etc...) and window.

# Example ```rust use static_init::{constructor,destructor,dynamic};

#[constructor] fn doinit(){ } //Care not to use priorities bellow 100 //as those high priorities are used by //the rust runtime. (The lower the number //the higher the priority) #[constructor(200)] fn dofirst(){ }

#[destructor] fn finaly() { } #[destructor(0)] fn ultimately() { }

#[dynamic] static V: Vec = vec![1,2,3];

#[dynamic(init,drop)] static mut V1: Vec = vec![1,2,3];

//Initialized before V1 //then destroyed after V1 #[dynamic(init=142,drop=142)] static mut INITANDDROP: Vec = vec![1,2,3];

fn main(){ asserteq!(V[0],1); unsafe{ asserteq!(V1[2],3); V1[2] = 42; assert_eq!(V1[2], 42); } } ```

# Attributes

All functions marked with the constructor attribute are run before main is started.

All function marked with the destructor attribute are run after main has returned.

Static variables marked with the dynamic attribute can be initialized before main start and optionaly droped after main returns.

The attributes constructor and destructor works by placing the marked function pointer in dedicated object file sections.

Priority ranges from 0 to 216-1. The absence of priority is equivalent to 216.

During program initialization: - constructors with priority 0 are the first called; - constructors without priority are called last.

During program termination, the order is reversed: - destructors without priority are the first called; - destructors with priority 0 are the last called.

# Comparisons against other crates

## lazystatic - lazystatic only provides const statics. - Each access to lazystatic statics costs 2ns on a x86. - lazystatic does not provide priorities.

## ctor - ctor only provides const statics. - ctor does not provide priorities.

# Documentation and details

## Mac - MACH_O specification - GCC source code gcc/config/darwin.c indicates that priorities are not supported.

Initialization functions pointers are placed in section "DATA,modinitfunc" and "DATA,modtermfunc"

## ELF plateforms: - info ld - linker script: ld --verbose - ELF specification

The runtime will run fonctions pointers of section ".initarray" at startup and function pointers in ".finiarray" at program exit. The linker place in the target object file sectio .initarray all sections from the source objects whose name is of the form .initarray.NNNNN in lexicographical order then the .initarray sections of those same source objects. It does equivalently with .finiarray and .fini_array.NNNN sections.

Usage can be seen in gcc source gcc/config/pru.c

Resources of libstdc++ are initialized with priority 100 (see gcc source libstdc++-v3/c++17/defaultresource.h) The rust standard library function that capture the environment and executable arguments is executed at priority 99. Some callbacks constructors and destructors with priority 0 are registered by rust/rtlibrary. Static C++ objects are usually initialized with no priority (TBC). lib-c resources are initialized by the C-runtime before any function in the initarray (whatever the priority) are executed.

## Windows