[][src]Attribute Macro static_init_macro::constructor

#[constructor]

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

#[constructor]
unsafe 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 and finaly constructors with no priority.

Safety

Constructor functions must be unsafe. Any access to dynamic statics with an equal or lower initialization priority will cause undefined behavior. (NB: usual static data initialized by a const expression are always in an initialized state so it is always safe to read them).

Notably, on Elf gnu variant platforms, accesses to the program argument or environment through std::env::* functionalities with a priority 65535-100 will cause undefined behavior. On windows thoses accesses std::env::* will never cause undefined behavior. On other plateforms (non gnu variant of unixes and mac), any access to std::env::* in a constructor, whatever its priority, will cause undefined behavior. In this last case, the information may be accessible in the /proc/self directory.

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

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

NB: Whatever the priority, constructors are run after initialization of libc resources. C++ static objects are initialized as constructors with no priorities. On ELF plateform, libstdc++ resources are initialized with priority 65535-100.

Constructor signature

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

But 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 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). Cf "glibc source"/csu/elf-init.c, and System V ABI.