You copied the Doc URL to your clipboard.

C++ initialization, construction and destruction

The C++ Standard places certain requirements on the construction and destruction of objects with static storage duration.

The ARM C++ compiler uses the .init_array area to achieve this. This is a const data array of self-relative pointers to functions. For example, you might have the following C++ translation unit, contained in the file test.cpp:

struct T
{
    T();
    ~T();
} t;
int f()
{
    return 4;
}
int i = f();

This translates into the following pseudocode:

         AREA ||.text||, CODE, READONLY
     int f()
    {
         return 4;
    }
     static void __sti___8_test_cpp
     {
         // construct 't' and register its destruction
         __aeabi_atexit(T::T(&t), &T::~T, &__dso_handle);
         i = f();
     }
         AREA ||.init_array||, DATA, READONLY
         DCD __sti___8_test_cpp - {PC}
         AREA ||.data||, DATA
     t   % 4
     i   % 4

This pseudocode is for illustration only. To see the code that is generated, compile the C++ source code with armclang --target aarch64-arm-none-eabi -S .

The linker collects each .init_array from the various translation units together. It is important that the .init_array is accumulated in the same order.

The library routine __cpp_initialize__aeabi_ is called from the C library startup code, __rt_lib_init, before main. __cpp_initialize__aeabi_ walks through the .init_array calling each function in turn. On exit, __rt_lib_shutdown calls __cxa_finalize.

Usually, there is at most one function for T::T(), mangled name _ZN1TC1Ev, one function for T::~T(), mangled name _ZN1TD1Ev, one __sti__ function, and four bytes of .init_array for each translation unit. The mangled name for the function f() is _Z1fv. There is no way to determine the initialization order between translation units.

Function-local static objects with destructors are also handled using __aeabi_atexit.

.init_array sections must be placed contiguously within the same region for their base and limit symbols to be accessible. If they are not, the linker generates an error.

Was this page helpful? Yes No