Attribute Macro static_init::constructor

source ·
#[constructor]
Expand description

Attribute for functions run at program initialization (before main).

#[constructor]
extern "C" fn initer () {
// run before main start
}

The execution order of constructors is unspecified. Nevertheless on ELF plateform (linux, any unixes but mac) and windows plateform a priority can be specified using the syntax constructor(<num>) where <num> is a number included in the range [0 ; 216-1].

Constructors with a priority of 65535 are run first (in unspecified order), then constructors with priority 65534 are run … then constructors with priority number 0

An abscence of priority is equivalent to a priority of 0.

#[constructor(0)]
extern "C" fn first () {
// run before main start
}

#[constructor(1)]
extern "C" fn then () {
// run before main start
}

§Safety

Any access to raw statics with an equal or lower initialization priority will cause undefined behavior. (NB: usual static data and lazy statics are always safe to access.

§About rust standard library runtime

During program constructions some functionnality of the standard library will be missing on unixes:

  • program argument as returned by std::env::args and environment variables as returned by std::env::vars will be emty on unixes other than linux-gnu. On linux/gnu they will be empty above priority
  • call to std::thread::current will panick.

  • standard streams may not be initialized.

  • Some signal handler installed by the standard library may not be installed

On windows all the standard library should appear initialized.

§Constructor signature

Constructor function should have type extern "C" fn() -> ().

On plateform where the program is linked with the gnu variant of libc (which covers all gnu variant platforms) constructor functions can take (or not) argc: i32, argv: **const u8, env: **const u8 as arguments. argc is the size of the argv sequence, argv and env both refer to null terminated contiguous sequence of pointer to c-string (c-strings are null terminated sequence of u8).

Also after the null terminating *const * const u8 of the environment variable list is found the auxilary vector that are information provided by the kernel. It is possible to retrieve from that vector information about the process and location of syscalls implemented in the vdso.

#[constructor]
extern "C" fn get_args_env(argc: i32, mut argv: *const *const u8, env: *const *const u8) {}