Здравствуйте, minorlogic, Вы писали:
M>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
M>Ваши идеи ? спасибо!
Первой строкой в main вызвать код, который зарегистрирует функции чем не устраивает?
Здравствуйте, minorlogic, Вы писали:
M>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
В BC++ 3.1 иожно было зарегистрировать некую функцию, которая вызывалась до main
В VC++ я такого не знаю
Единственно, что могу предложить умозрительно — взять исходники стартового кода (из которого вызывается main), добавить туда свою функцию (которая и регистрирует то, что тебе надо)и ее вызов, откомпилировать и заменить им стандартный стартовый код.
О подробностях не спрашивай — никогда такого не делал. Если сделаешь и получится — думаю, это будет интересным для многих, так что отпишись.
Здравствуйте, 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.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Предложи свой способ вызвать некую функцию до main (хоть с рефакторингом, хоть с чем угодно) — тогда и поговорим. Пока что от тебя я вижу только совет, который годится не для minorlogic, а для некоего школьника, впервые узнавшего про язык C.
Мы не задачки из школьного учебника решаем — для вызова, чего либо до main нужны очень серьезные основания. Пока я не понял зачем это нужно, поэтому банальный совет — избегать глобальных и статических типов, делать порядок инициализации явным.
Здравствуйте, minorlogic, Вы писали:
M>Задача следующая.
M>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
M>Ваши идеи ? спасибо!
Здравствуйте, MTD, Вы писали:
PD>>До этого будут вызваны конструкторы глобальных объектов.
MTD>И статических, но вопрос был: "Первой строкой в main вызвать код, который зарегистрирует функции чем не устраивает?"
Тем, что , возможно, этим конструкторам требуется, чтобы к моменту их выполнения регистрация уже прошла.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Тем, что , возможно, этим конструкторам требуется, чтобы к моменту их выполнения регистрация уже прошла.
Это твои догадки, а мне чтобы помочь автору, нужна была дополнительная информация от него. Если все так, как ты написал, то у автора проблема — нет никаких гарантий, что объекты не будут созданы раньше, чем пройдет регистрация, хоть и до main.
Здравствуйте, MTD, Вы писали:
MTD>Это твои догадки, а мне чтобы помочь автору, нужна была дополнительная информация от него. Если все так, как ты написал, то у автора проблема — нет никаких гарантий, что объекты не будут созданы раньше, чем пройдет регистрация, хоть и до main.
Судя по тому, что я знаю об авторе, догадаться написать нечто в самом начале main он смог бы и без чьей-то помощи. Если он задал вопрос — значит, ему нужно именно до main что-то сделать.
Здравствуйте, Pavel Dvorkin, Вы писали:
MTD>>Помогло, помогло. Мы тут друг-другу помогаем. Ты мне про ТС рассказал, я тебе про то, что статические объекты до main создаются — оба стали знать чуть больше
PD>Спасибо большое.
Не за что.
PD>Будет к тому же неплохо, если ты разберешься с тем, что статические объекты, описанные внутри функции , создаются при первом входе в функцию, а статические объекты, описанные вне функций, есть те же глобальные объекты, область видимости которых при компиляции ограничена файлом.
Молодец, книжку открыл, еще почитай про статические объекты классов, не повредит.
Здравствуйте, minorlogic, Вы писали:
A>>Непонятная задача, (большое к-во функций) * (В каждой есть макрос в который мы можем добавить что угодно) надо зарегистрировать (где, в паспортом столе?)
M>Например заригестрировать имена функций во внешнем хранилище , некий API
Переименуйте имеющийся main в oldmain, напишите свой main, зарегистрируйте в нем что вам нужно, потом вызывайте "oldmain"
Здравствуйте, MTD, Вы писали:
PD>>Будет к тому же неплохо, если ты разберешься с тем, что статические объекты, описанные внутри функции , создаются при первом входе в функцию, а статические объекты, описанные вне функций, есть те же глобальные объекты, область видимости которых при компиляции ограничена файлом.
MTD>Молодец, книжку открыл, еще почитай про статические объекты классов, не повредит.
Тоже пока не помогли , создаются при первом создании экземпляра класса.
M>Необходимо зарегистрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
M>Ваши идеи ? спасибо!
Я бы пошёл по пути кодогенерации. В макрос бы добавил что-то вроде #pragma message("Func2reg: " __FUNCTION__ ), затем передал бы вывод компилятора в awk (фильтр строк по Func2reg), который бы сделал список имён функций. Затем тем же awk-ом или каким-то другим скриптом сгенерировал бы cpp-файл с одной функцией, регистрирующей нужные имена. А в начало main()-а бы добавил вызов этой самой функции.
Со статическими конструкторами и прочими способами вызова кода до main() я больше никогда по доброй воле связываться не буду. Ибо адский гемор с отладкой, воспроизводимостью багов, поведением библиотек (которые тоже любят инициализацию до main()), с динамическими библиотеками.
Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main.
В каждой из функций уже есть макрос в который мы можем добавить что угодно.
Хм, тут раздают минусы?
M>Задача следующая.
M>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
Непонятная задача, (большое к-во функций) * (В каждой есть макрос в который мы можем добавить что угодно) надо зарегистрировать (где, в паспортом столе?)
M>Ваши идеи ? спасибо!
Опишите функции до main, может они зарегистрируются сами.
Здравствуйте, Pavel Dvorkin, Вы писали:
MTD>>Первой строкой в main вызвать код, который зарегистрирует функции чем не устраивает?
PD>До этого будут вызваны конструкторы глобальных объектов.
И статических, но вопрос был: "Первой строкой в main вызвать код, который зарегистрирует функции чем не устраивает?"
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Судя по тому, что я знаю об авторе, догадаться написать нечто в самом начале main он смог бы и без чьей-то помощи. Если он задал вопрос — значит, ему нужно именно до main что-то сделать.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Судя по тому, что я знаю об авторе, догадаться написать нечто в самом начале main он смог бы и без чьей-то помощи. Если он задал вопрос — значит, ему нужно именно до main что-то сделать.
а остальные должны быть прорицателями?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>В BC++ 3.1 иожно было зарегистрировать некую функцию, которая вызывалась до main PD>В VC++ я такого не знаю
PD>Единственно, что могу предложить умозрительно — взять исходники стартового кода (из которого вызывается main), добавить туда свою функцию (которая и регистрирует то, что тебе надо)и ее вызов, откомпилировать и заменить им стандартный стартовый код.
Вообще, вот такой подход — нахачить на ровном месте и получить кучу проблем, вместо нормального рефакторинга, характерно для студента, но никак не для разработчика с опытом.
Здравствуйте, MTD, Вы писали:
MTD>Вообще, вот такой подход — нахачить на ровном месте и получить кучу проблем, вместо нормального рефакторинга, характерно для студента, но никак не для разработчика с опытом.
Предложи свой способ вызвать некую функцию до main (хоть с рефакторингом, хоть с чем угодно) — тогда и поговорим. Пока что от тебя я вижу только совет, который годится не для minorlogic, а для некоего школьника, впервые узнавшего про язык C.
Здравствуйте, niXman, Вы писали:
PD>>Судя по тому, что я знаю об авторе, догадаться написать нечто в самом начале main он смог бы и без чьей-то помощи. Если он задал вопрос — значит, ему нужно именно до main что-то сделать. X>а остальные должны быть прорицателями?
Я согласен, что ТС не очень четко сформулировал задачу, но никак не могу поверить, что он бы задал вопрос : как мне сделать что-то первым действием в main
Здравствуйте, MTD, Вы писали:
MTD>Здравствуйте, minorlogic, Вы писали:
M>>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
M>>Ваши идеи ? спасибо!
MTD>Первой строкой в main вызвать код, который зарегистрирует функции чем не устраивает?
не устраивает по условию задачи. А на практике , код main нельзя модифицировать.
A>Непонятная задача, (большое к-во функций) * (В каждой есть макрос в который мы можем добавить что угодно) надо зарегистрировать (где, в паспортом столе?)
Например заригестрировать имена функций во внешнем хранилище , некий API
Здравствуйте, niXman, Вы писали:
X>Здравствуйте, minorlogic, Вы писали:
M>>Имелось в виду записать ее имя (параметры) в внешнем хранилище. X>LD_PRELOAD
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Сомневаюсь, что тебе это помогло...
Помогло, помогло. Мы тут друг-другу помогаем. Ты мне про ТС рассказал, я тебе про то, что статические объекты до main создаются — оба стали знать чуть больше
Здравствуйте, MTD, Вы писали:
MTD>Помогло, помогло. Мы тут друг-другу помогаем. Ты мне про ТС рассказал, я тебе про то, что статические объекты до main создаются — оба стали знать чуть больше
Спасибо большое. Будет к тому же неплохо, если ты разберешься с тем, что статические объекты, описанные внутри функции , создаются при первом входе в функцию, а статические объекты, описанные вне функций, есть те же глобальные объекты, область видимости которых при компиляции ограничена файлом.
Здравствуйте, MTD, Вы писали:
MTD>Молодец, книжку открыл, еще почитай про статические объекты классов, не повредит.
Читать книги, безусловно, полезно. Хотя бы для того, чтобы знать, что у классов есть поля и методы (в том числе статические), а не объекты. Что же касается статических полей классов — то это фактически глобальные переменные, приписанные к классу.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Читать книги, безусловно, полезно. Хотя бы для того, чтобы знать, что у классов есть поля и методы (в том числе статические), а не объекты. Что же касается статических полей классов — то это фактически глобальные переменные, приписанные к классу.
Отлично! Почти все фигуры выучили, скоро будем учится играть
Здравствуйте, minorlogic, Вы писали:
M>Задача следующая.
M>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
M>Ваши идеи ? спасибо!
Здравствуйте, 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>Ваши идеи ? спасибо!
Глобальный объект класса, который в конструкторе все сделает не подходит?
Здравствуйте, minorlogic, Вы писали:
M>Здравствуйте, Kernan, Вы писали:
K>>Здравствуйте, minorlogic, Вы писали:
M>>>Задача следующая.
M>>>Необходимо зарегестрировать имена большого к-ва функций которые НЕ вызываются для регистрации и до вызова main. M>>>В каждой из функций уже есть макрос в который мы можем добавить что угодно.
M>>>Ваши идеи ? спасибо! K>>На ум приходит только использование статического объекта и сохранения всего и вся внутри его конструктора.
M>для этого функцию надо будет вызвать. Зачем? Либо я не совсем понял тебя.
Здравствуйте, minorlogic, Вы писали:
M>То что надо , но макрос расположен внутри функции "sum"
Внутри {} в реализации функции в .cpp модулях? С запретом на вызов этих функций? Тогда только внешний парсер.
Шаблоны внутри функций специализировать нельзя, статические члены в локальных классах функции тоже нельзя.
А обычные макросы за пределы области видимости данного .cpp не выйдут.
Вообще странная какая-то задача, почему ничего нельзя менять кроме макроса внутри определения фукнций?
Добавлением макроса к объявлению функций, можно было бы вoобще все в compile time получить.
Здравствуйте, 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 есть, вроде как такая фича -- совмещать бинарные блоки, отличающиеся только своим адресом, в один и тот же.
Так что, если в формальном примере, не было никаких отличий между разными инстанциациями метода, то линкер вполне логично мог оставить тока одну...
Если сделать реальный односвязный список, с саморегистрацией элементов в конструкторах нод, то, скорее всего, само собой не выкинется....
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском