GCC __attribute __ ((constructor)) вызывается перед конструктором объекта - PullRequest
0 голосов
/ 05 июня 2018

В моей общей библиотеке мне нужно загрузить некоторые данные в unordered_map, и я пытаюсь сделать это с помощью функции, отмеченной __ attribute __ ((constructor)).Однако я получил SIGFPE на каждой операции с картой.После некоторого изучения стека overoverflow я обнаружил, что это означает, что unordered_map неинициализирован.Это довольно неожиданно и непонятно для меня, потому что, на первый взгляд, это нарушает контракты C ++.Кто-нибудь может помочь с тем, как я могу запустить этот метод после запуска конструкторов?Вот рабочий пример с моим собственным конструктором, который показывает, что он не называется:

#include <stdio.h>

class Ala {
    int i;
public:
    Ala() {
        printf("constructor called\n");
        i = 3;
    }

    int getI() {
        return i;
    }
};

Ala a;

__attribute__((constructor))
static void initialize_shared_library() {
    printf("initializing shared library\n");
    printf("a.i=%d\n", a.getI());
    printf("end of initialization of the shared library\n");
}

В результате получается

initializing shared library
a.i=0
end of initialization of the shared library
constructor called

, однако, если вы попытаетесь использовать std :: cout вместоprintfs затем сразу переходит в SEGFAULT (потому что конструктор потоков не запускался)

Ответы [ 3 ]

0 голосов
/ 05 июня 2018

Если вы просто хотите запустить что-то после инициализации a, есть несколько способов сделать это, не выходя из Standard C ++;вот один:

struct Ala2 : Ala
{
    Ala2()
    {
         // your init code here
    }
};

Ala2 a;
0 голосов
/ 05 июня 2018

Если вы используете функцию, которая возвращает статическую локальную переменную, переменная будет инициализирована при первом вызове функции.См .: Когда статические переменные уровня функции выделяются / инициализируются?

struct Ala {
   // Your code here
   static Ala& get_singleton();
};

Ala& Ala::get_singleton() {
   static Ala singleton;
   return singleton;
}

static void initialize_shared_library() {
    Ala& a = get_singleton();
    printf("initializing shared library\n");
    printf("a.i=%d\n", a.getI());
    printf("end of initialization of the shared library\n");
}

Как уже говорили другие, обычно лучше инкапсулировать весь процесс инициализации в объекте и позволитьконструктор выполняет всю работу за вас (тело конструктора выполняется после инициализации всех членов класса).

0 голосов
/ 05 июня 2018

__attribute__((constructor)) является расширением компилятора, и поэтому вы оставили сферы стандарта C ++.Похоже, что функции конструктора GCC запускаются до глобальной инициализации.

Способ исправить это - использовать другую ванильную конструкцию C ++, например глобальный объект, инициализация которого правильно упорядочена путем определения его в том же TU, что и вашдругие глобальные:

Ala a;

static void initialize_shared_library() {
    printf("initializing shared library\n");
    printf("a.i=%d\n", a.getI());
    printf("end of initialization of the shared library\n");
}

static int const do_init = (initialize_shared_library(), 0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...