Здравствуйте, 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.