При использовании глобальных, то есть не внутри функции, объектов, компилятор и компоновщик формируют массивы указателей на конструкторы и деструкторы (при необходимости). Массивы называются .init_ar и .fini_ar .
Поскольку идентификаторы в С++ не могут начинаться с точки, эти идентификаторы недоступны напрямую.
Чтобы получить к ним доступ, приходится воспользоваться скриптом для компоновщика:
...
  .init_array : ALIGN(0x10) { 
    PROVIDE_HIDDEN(__init_array_begin = .);
    *(.init_array) ;
    PROVIDE_HIDDEN(__init_array_end = .);
  }
  .fini_array : ALIGN(0x10) { 
    PROVIDE_HIDDEN(__fini_array_begin = .);
    *(.fini_array) ;
    PROVIDE_HIDDEN(__fini_array_end = .);
  }
...Теперь можно использовать идентификаторы С в коде
using func_t = void(*)(void);
extern "C" {
	extern func_t __init_array_begin[];
	extern func_t __init_array_end[];
}Необходимо определять именно как массивы, иначе вместо использования адреса конструктора как адреса функции, будет попытка вызова кода конструктора как адреса функции.
Обработка массивов прямолинейная, с помощью цикла:
for(auto _array=__init_array_begin; _array != __init_array_end; _array++)
    (*_array)();
Аналогично обрабатывается и массив деструкторов.