Здравствуйте, minorlogic, Вы писали:
M>Задача следующая.
M>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
M>Ваши идеи ? спасибо!
А если библиотеку таких фнукций оформить? С её последующим подключением.
Здравствуйте, minorlogic, Вы писали:
M>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
#include <map>
#include <string>
#include <iostream>
using namespace std;
map<string,void*>& FuncMap()
{
static map<string,void*> funcMap;
return funcMap;
}
#define REG(func) bool registered_##func = (FuncMap().emplace( #func, (void*)&func ), true);
int sum(int a, int b)
{
return a + b;
}
REG( sum )
int main()
{
cout << "&sum = " << FuncMap().at( "sum" ) << endl;
return 0;
}
Здравствуйте, minorlogic, Вы писали:
M>Ваши идеи ? спасибо!
Если я понял верно, то проблема в том, что бы сконструировать уникальный статический объект на функцию но сделать это не во время первого вызова, а во время создания статических объектов или раньше?
Я бы попробовал написать шаблон класса, со статическим полем, и параметризовать этот шаблон указателем на функцию, например...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, minorlogic, Вы писали:
M>Задача следующая.
M>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
M>Ваши идеи ? спасибо!
На ум приходит только использование статического объекта и сохранения всего и вся внутри его конструктора.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, minorlogic, Вы писали:
M>>Ваши идеи ? спасибо!
E>Если я понял верно, то проблема в том, что бы сконструировать уникальный статический объект на функцию но сделать это не во время первого вызова, а во время создания статических объектов или раньше?
E>Я бы попробовал написать шаблон класса, со статическим полем, и параметризовать этот шаблон указателем на функцию, например...
Насколько помню статическое поле будет создано при конструировании первого экземпляра класса
Здравствуйте, Kernan, Вы писали:
K>Здравствуйте, minorlogic, Вы писали:
M>>Задача следующая.
M>>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
M>>Ваши идеи ? спасибо! K>На ум приходит только использование статического объекта и сохранения всего и вся внутри его конструктора.
Здравствуйте, minorlogic, Вы писали:
M>Насколько помню статическое поле будет создано при конструировании первого экземпляра класса
Пруф?
В конце концов может же быть класс, у которого вообще все члены статические. И поля и методы, и ничего. работает вроде как...
Может POI там будет рядом с конструктором, например или ещё чего в таком роде?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, minorlogic, Вы писали:
M>Задача следующая.
M>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
M>Ваши идеи ? спасибо!
Глобальный объект класса, который в конструкторе все сделает не подходит?
M>Необходимо зарегистрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
M>Ваши идеи ? спасибо!
Я бы пошёл по пути кодогенерации. В макрос бы добавил что-то вроде #pragma message("Func2reg: " __FUNCTION__ ), затем передал бы вывод компилятора в awk (фильтр строк по Func2reg), который бы сделал список имён функций. Затем тем же awk-ом или каким-то другим скриптом сгенерировал бы cpp-файл с одной функцией, регистрирующей нужные имена. А в начало main()-а бы добавил вызов этой самой функции.
Со статическими конструкторами и прочими способами вызова кода до main() я больше никогда по доброй воле связываться не буду. Ибо адский гемор с отладкой, воспроизводимостью багов, поведением библиотек (которые тоже любят инициализацию до main()), с динамическими библиотеками.
Здравствуйте, minorlogic, Вы писали:
M>Здравствуйте, Kernan, Вы писали:
K>>Здравствуйте, minorlogic, Вы писали:
M>>>Задача следующая.
M>>>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>>>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
M>>>Ваши идеи ? спасибо! K>>На ум приходит только использование статического объекта и сохранения всего и вся внутри его конструктора.
M>для этого функцию надо будет вызвать. Зачем? Либо я не совсем понял тебя.
Здравствуйте, minorlogic, Вы писали:
M>То что надо , но макрос расположен внутри функции "sum"
Внутри {} в реализации функции в .cpp модулях? С запретом на вызов этих функций? Тогда только внешний парсер.
Шаблоны внутри функций специализировать нельзя, статические члены в локальных классах функции тоже нельзя.
А обычные макросы за пределы области видимости данного .cpp не выйдут.
Вообще странная какая-то задача, почему ничего нельзя менять кроме макроса внутри определения фукнций?
Добавлением макроса к объявлению функций, можно было бы вoобще все в compile time получить.
Здравствуйте, minorlogic, Вы писали:
M>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
Для С++11
#include <cstdio>
// пусть у нас вот такое апи для регистрации функцийvoid register_smth(void(*f)(), const char* s)
{
printf("registered %s = %p.\n", s, (void*)f);
}
// создаём глобальную переменную, которая инициализируется с помощью вызова функтора Ftemplate< 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; \
//endmacrovoid foo()
{
REGISTER(foo);
printf("going foo!\n");
}
void bar()
{
REGISTER(bar);
printf("going bar!\n");
}
int main() {}
Разумеется, проблема гонок на старте никуда не денется. Пользоваться реестром функций гарантированно можно только после входа в main.
Здравствуйте, minorlogic, Вы писали:
M>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
M>Ваши идеи ? спасибо!
.
Идея такая: объявить шаблонный класс содержащий статическую константу (типа массив константных строк) и создать глобальный объект этого класса. А в каждой функции написать специализацию указанного шаблонного класса строковой константой.
Ещё, теоретически, для этого можно использовать User-defined literals
operator "" X<'c1', 'c2', … , 'ck'>()
и вроде бы со следующего стандарта всё такое может быть будет возможно.
Короче, надо посмотреть поддержку Literal operator templates for strings что-то типа этого
Что же касается текущей задачи, то наверное её можно решить как то так:
— в каждой функции пишем нечто такое:
Теперь у всех классов потомков FNameBase есть статическое поле FNameBase::m_strName содержащие имя из функции. Надо придумать как их собрать в список, а список присвоить глобальной переменной...
Линкер VS правда все равно выкидывает ForceLinkVariable.
Вот так только сработало:
// препятствуем тому, чтобы линкер выкинул её за ненадобностью:
// адрес переменной является параметром шаблонаtemplate< int* adr > struct ForceLinkVariable { int* link = adr; };
DD>Линкер VS правда все равно выкидывает ForceLinkVariable. DD>Вот так только сработало: DD>
// препятствуем тому, чтобы линкер выкинул её за ненадобностью:
DD>// адрес переменной является параметром шаблона
DD>template< int* adr > struct ForceLinkVariable { int* link = adr; };
У VS есть, вроде как такая фича -- совмещать бинарные блоки, отличающиеся только своим адресом, в один и тот же.
Так что, если в формальном примере, не было никаких отличий между разными инстанциациями метода, то линкер вполне логично мог оставить тока одну...
Если сделать реальный односвязный список, с саморегистрацией элементов в конструкторах нод, то, скорее всего, само собой не выкинется....
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском