Re: Зарегестрировать функции до вызова main
От: Кодт Россия  
Дата: 10.02.14 11:26
Оценка: 12 (2)
Здравствуйте, minorlogic, Вы писали:

M>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main.

M>В каждой из функций уже есть макрос в который мы можем добавить что угодно.

Для С++11
#include <cstdio>

// пусть у нас вот такое апи для регистрации функций
void register_smth(void(*f)(), const char* s)
{
    printf("registered %s = %p.\n", s, (void*)f);
}


// создаём глобальную переменную, которая инициализируется с помощью вызова функтора F
template< class F > struct Executor
{
    static int LinkPoint;
    static int setup() { F()(); return 0; }
};
template< class F > int Executor<F>::LinkPoint = Executor<F>::setup();

// препятствуем тому, чтобы линкер выкинул её за ненадобностью:
// адрес переменной является параметром шаблона
template< int* > struct ForceLinkVariable {};

// создаём шаблон класса, зависящего от класса, зависящего от переменной, зависящей от функтора;
// если где-то есть воплощение этого класса, то и всё остальное воплотится
template< class F > struct Registrator : ForceLinkVariable< &Executor<F>::LinkPoint > {};

// код регистрации функции:
// локальный класс-функтор (С++11 позволяет локальным классам быть параметрами шаблонов)
// и упоминание о регистраторе (нулевой оверхед, т.к. Registrator это POD)
#define REGISTER(fun) \
    struct PleaseRegisterMe \
    { \
        void operator()() const { register_smth(fun, #fun); } \
    }; \
    static Registrator<PleaseRegisterMe> registrator; \
    //endmacro

void foo()
{
    REGISTER(foo);
    printf("going foo!\n");
}
void bar()
{
    REGISTER(bar);
    printf("going bar!\n");
}

int main() {}


Разумеется, проблема гонок на старте никуда не денется. Пользоваться реестром функций гарантированно можно только после входа в main.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.