Re: Зарегестрировать функции до вызова main
От: smeeld  
Дата: 09.02.14 22:18
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>Задача следующая.


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

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

M>Ваши идеи ? спасибо!


А если библиотеку таких фнукций оформить? С её последующим подключением.
Re: Зарегестрировать функции до вызова main
От: Desert Dragon Россия  
Дата: 10.02.14 01:54
Оценка:
Здравствуйте, 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;
}
Re: Зарегестрировать функции до вызова main
От: Erop Россия  
Дата: 10.02.14 08:00
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>Ваши идеи ? спасибо!


Если я понял верно, то проблема в том, что бы сконструировать уникальный статический объект на функцию но сделать это не во время первого вызова, а во время создания статических объектов или раньше?

Я бы попробовал написать шаблон класса, со статическим полем, и параметризовать этот шаблон указателем на функцию, например...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Зарегестрировать функции до вызова main
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 10.02.14 09:17
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>Задача следующая.


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

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

M>Ваши идеи ? спасибо!

На ум приходит только использование статического объекта и сохранения всего и вся внутри его конструктора.
Sic luceat lux!
Re[2]: Зарегестрировать функции до вызова main
От: minorlogic Украина  
Дата: 10.02.14 09:24
Оценка:
Здравствуйте, Desert Dragon, Вы писали:

То что надо , но макрос расположен внутри функции "sum"
... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[2]: Зарегестрировать функции до вызова main
От: minorlogic Украина  
Дата: 10.02.14 09:25
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, minorlogic, Вы писали:


M>>Ваши идеи ? спасибо!


E>Если я понял верно, то проблема в том, что бы сконструировать уникальный статический объект на функцию но сделать это не во время первого вызова, а во время создания статических объектов или раньше?


E>Я бы попробовал написать шаблон класса, со статическим полем, и параметризовать этот шаблон указателем на функцию, например...


Насколько помню статическое поле будет создано при конструировании первого экземпляра класса
... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[2]: Зарегестрировать функции до вызова main
От: minorlogic Украина  
Дата: 10.02.14 09:25
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Здравствуйте, minorlogic, Вы писали:


M>>Задача следующая.


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

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

M>>Ваши идеи ? спасибо!

K>На ум приходит только использование статического объекта и сохранения всего и вся внутри его конструктора.

для этого функцию надо будет вызвать.
... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[3]: Зарегестрировать функции до вызова main
От: Erop Россия  
Дата: 10.02.14 09:46
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>Насколько помню статическое поле будет создано при конструировании первого экземпляра класса


Пруф?
В конце концов может же быть класс, у которого вообще все члены статические. И поля и методы, и ничего. работает вроде как...
Может POI там будет рядом с конструктором, например или ещё чего в таком роде?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Зарегестрировать функции до вызова main
От: MTimur  
Дата: 10.02.14 09:59
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>Задача следующая.


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

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

M>Ваши идеи ? спасибо!


Глобальный объект класса, который в конструкторе все сделает не подходит?
Re: Зарегестрировать функции до вызова main
От: Mazay Россия  
Дата: 10.02.14 10:12
Оценка: +1
Здравствуйте, minorlogic, Вы писали:


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

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

M>Ваши идеи ? спасибо!


Я бы пошёл по пути кодогенерации. В макрос бы добавил что-то вроде #pragma message("Func2reg: " __FUNCTION__ ), затем передал бы вывод компилятора в awk (фильтр строк по Func2reg), который бы сделал список имён функций. Затем тем же awk-ом или каким-то другим скриптом сгенерировал бы cpp-файл с одной функцией, регистрирующей нужные имена. А в начало main()-а бы добавил вызов этой самой функции.

Со статическими конструкторами и прочими способами вызова кода до main() я больше никогда по доброй воле связываться не буду. Ибо адский гемор с отладкой, воспроизводимостью багов, поведением библиотек (которые тоже любят инициализацию до main()), с динамическими библиотеками.
Главное гармония ...
Re[3]: Зарегестрировать функции до вызова main
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 10.02.14 10:57
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>Здравствуйте, Kernan, Вы писали:


K>>Здравствуйте, minorlogic, Вы писали:


M>>>Задача следующая.


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

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

M>>>Ваши идеи ? спасибо!

K>>На ум приходит только использование статического объекта и сохранения всего и вся внутри его конструктора.

M>для этого функцию надо будет вызвать.

Зачем? Либо я не совсем понял тебя.
Sic luceat lux!
Re[3]: Зарегестрировать функции до вызова main
От: Desert Dragon Россия  
Дата: 10.02.14 10:58
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>То что надо , но макрос расположен внутри функции "sum"


Внутри {} в реализации функции в .cpp модулях? С запретом на вызов этих функций? Тогда только внешний парсер.
Шаблоны внутри функций специализировать нельзя, статические члены в локальных классах функции тоже нельзя.
А обычные макросы за пределы области видимости данного .cpp не выйдут.

Вообще странная какая-то задача, почему ничего нельзя менять кроме макроса внутри определения фукнций?
Добавлением макроса к объявлению функций, можно было бы вoобще все в compile time получить.
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.
Перекуём баги на фичи!
Re[4]: Зарегестрировать функции до вызова main
От: minorlogic Украина  
Дата: 10.02.14 12:27
Оценка:
Здравствуйте, Kernan, Вы писали:

M>>для этого функцию надо будет вызвать.

K>Зачем? Либо я не совсем понял тебя.

Я подумал ты про статический объект внутри функции. А так не подходит под условие задачи.
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[3]: Зарегестрировать функции до вызова main
От: enji  
Дата: 10.02.14 12:29
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>Не понял как это будет работать , можно код целиком с main ? спасибо


#define INIT \
  namespace { struct Init##__LINE__ { \
    Init##__LINE__(); \
  } init##__LINE__; } /* в прошлом примере забыл создать объект */ \ 
  Init##__LINE__::Init##__LINE__()

typedef void (*Func)(); 

// func.cpp
std::vector<Func>& storage() { 
  static std::vector<Func> st;
  return st;
} 

void registerFunc(Func f) {
  storage().push_back(f);
}

// a.cpp
void func1() {}
INIT { // код будет выполнен до вызова main()
  registerFunc(func1); 
}

// b.cpp
void func2() {}
INIT { // код будет выполнен до вызова main()
  registerFunc(func2); 
}

// main.cpp
void main() { 
  for (auto f : storage()) 
    f();
}
Re[2]: Зарегестрировать функции до вызова main
От: minorlogic Украина  
Дата: 10.02.14 12:36
Оценка:
Здравствуйте, MTimur, Вы писали:

MT>Глобальный объект класса, который в конструкторе все сделает не подходит?


Подойдет если будут выполнены условия задачи. А именно, вытащить к примеру название функции из ее тела
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[2]: Зарегестрировать функции до вызова main
От: minorlogic Украина  
Дата: 10.02.14 13:09
Оценка:
Отлично, именно то что и требуется. Коллеги бьются , как это сделать на C++03. Ход мысли примерно тотже использовали.
Ищу работу, 3D, SLAM, computer graphics/vision.
Re: Зарегестрировать функции до вызова main
От: B0FEE664  
Дата: 10.02.14 14:02
Оценка:
Здравствуйте, minorlogic, Вы писали:

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

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

M>Ваши идеи ? спасибо!


Два года назад я уже задавал подобный вопрос здесь собрать строковые константы в список
Автор: B0FEE664
Дата: 31.01.12
.
Идея такая: объявить шаблонный класс содержащий статическую константу (типа массив константных строк) и создать глобальный объект этого класса. А в каждой функции написать специализацию указанного шаблонного класса строковой константой.

Ещё, теоретически, для этого можно использовать User-defined literals
operator "" X<'c1', 'c2', … , 'ck'>()
и вроде бы со следующего стандарта всё такое может быть будет возможно.
Короче, надо посмотреть поддержку Literal operator templates for strings
что-то типа этого

Что же касается текущей задачи, то наверное её можно решить как то так:
— в каждой функции пишем нечто такое:

FName<'N', 'a', 'm', 'e', 'O', 'f', 'T', 'h', 'e', 'F', 'u', 'n', 'c', 't', 'i', 'o', 'n'> oName;


Создаём класс содержащий это имя:
template<char cHead, char... cTail>
class FName<cHead, cTail...> : public FNameBase{

public: 
    static const std::string m_strName;
};

template<char cHead, char... cTail>
const std::string FNames::m_strName = ConCat(cHead, cTail...);


Где ConCat это:
std::string ConCat(char ch)
{
  return std::string(1, ch);
}

template<char ch, char... Args>
std::string ConCat(char ch, Args... args)
{
  return ch + ConCat(args...);
}


Теперь у всех классов потомков FNameBase есть статическое поле FNameBase::m_strName содержащие имя из функции. Надо придумать как их собрать в список, а список присвоить глобальной переменной...
И каждый день — без права на ошибку...
Re[2]: Зарегестрировать функции до вызова main
От: Desert Dragon Россия  
Дата: 10.02.14 14:03
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Для С++11


Век живи, век учись

Линкер VS правда все равно выкидывает ForceLinkVariable.
Вот так только сработало:
// препятствуем тому, чтобы линкер выкинул её за ненадобностью:
// адрес переменной является параметром шаблона
template< int* adr > struct ForceLinkVariable { int* link = adr; };
Re[3]: Зарегестрировать функции до вызова main
От: Erop Россия  
Дата: 10.02.14 20:34
Оценка:
Здравствуйте, Desert Dragon, Вы писали:


DD>Линкер VS правда все равно выкидывает ForceLinkVariable.

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


У VS есть, вроде как такая фича -- совмещать бинарные блоки, отличающиеся только своим адресом, в один и тот же.
Так что, если в формальном примере, не было никаких отличий между разными инстанциациями метода, то линкер вполне логично мог оставить тока одну...
Если сделать реальный односвязный список, с саморегистрацией элементов в конструкторах нод, то, скорее всего, само собой не выкинется....
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.