[][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 destructors 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 0 are initialized first (in unspecified order), then statics with priority number 1 are initialized ... then statics with priority number 65535 and finaly statics with no 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=65535) and dynamic(<num>) to dynamic(init=65535). In the absence of init the static will not be created dynamically. 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 65536 and finaly statics with priority 0 are the last dropped.

If a priority is not explicitly specified for drop, it will equal that of init.

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