Attribute Macro static_init_macro::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.
Safety
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)]
extern "C" fn first () {
// run before main start
}
#[constructor(1)]
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 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.