[][src]Attribute Macro static_init::dynamic

#[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)};

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)};

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)};