Attribute Macro static_init::dynamic [−][src]
#[dynamic]
Statics initialized with non const functions.
Statics on which this attribute is applied will be be initialized at run time (optionaly see bellow), before main start. This allow statics initialization with non const expressions.
Safety
Initialization expressions must be unsafe blocks. During initialization, any access to other "dynamic" statics initialized with a lower priority will cause undefined behavior. Similarly, during drop any access to a "dynamic" static dropped with a lower priority will cause undefined behavior.
struct A(i32); impl A { //new is not const fn new(v:i32) -> A { A(v) } } #[dynamic] static V :A = unsafe{A::new(42)};
Execution Order
The execution order of "dynamic" static initializations is unspecified. Nevertheless on ELF plateform (linux,any unixes but mac) and
windows plateform a priority can be specified using the syntax dynamic(<num>)
where
<num>
is a number included in the range [0 ; 216-1].
Statics with priority number 65535 are initialized first (in unspecified order), then statics with priority number 65534 are initialized ... then statics with priority number 0 and finaly statics without priority.
struct A(i32); impl A { //new is not const fn new(v:i32) -> A { A(v) } } //V1 must be initialized first //because V2 uses the value of V1. #[dynamic(10)] static mut V1 :A = unsafe{A::new(33)}; #[dynamic(20)] static V2 :A = unsafe{A::new(V1.0 + 9)};
Full syntax and dropped statics
Finaly the full syntax is for the attribute is:
"dynamic" [ "(" <dyn_opts> ")" ]
dyn_opts:
<dyn_opt>
<dyn_opt>, <dyn_opts>
dyn_opt:
"init" [ "=" <priority> ]
"drop" [ "=" <priority> ]
The macro attribute dynamic
is equivalent to dynamic(init=0)
and dynamic(<num>)
to dynamic(init=<num>)
. In the absence of init
the static will be const initialized as usual static. The drop
option
cause the static to be droped after main returns. The priority has the
same semantic as for the destructor attribute: statics without priority
are droped first, then statics with priority 0,... and finaly statics with priority
65535 are the last dropped.
If the drop priority is not explicitly specified, it will equal that of the initializaton priority.
struct A(i32); impl A { //new is not const fn new(v:i32) -> A { A(v) } //new is not const const fn const_new(v:i32) -> A { A(v) } } impl Drop for A { fn drop(&mut self) {} } //const initialized droped after main exit #[dynamic(drop)] static mut V1 :A = unsafe{A::new_const(33)}; //initialized before V1 and droped after V1 #[dynamic(20,drop=10)] static V2 :A = unsafe{A::new(10)}; // if a drop priority is not specified, it equals the // init priority so the attribute bellow is equivalent to // #[dynamic(init=20, drop=20) #[dynamic(init=20,drop)] static V3 :A = unsafe{A::new(10)}; // not droped #[dynamic(init)] static V4 :A = unsafe{A::new(10)}; // not droped #[dynamic] static V5 :A = unsafe{A::new(10)}; // not droped #[dynamic(10)] static V6 :A = unsafe{A::new(10)};
Actual type of "dynamic" statics
A mutable "dynamic" static declared to have type T
, will have type static_init::Static<T>
.
A mutable "dynamic" static declared to have type T
, will have type static_init::ConstStatic<T>
.
Those types are opaque types that implements Deref<T>
. static_init::Static
also implements
DerefMut
.
// V has type static_init::ConstStatic<i32> #[dynamic] static V :i32 = unsafe{0}; // W has type static_init::Static<i32> #[dynamic] static W :i32 = unsafe{0};