LINUX.ORG.RU

Использование new перед main()

 


1

2

Привет.
Я вот давно думаю - а можно ли использовать new expression перед main (например, в конструкторе глобального объекта). Я прошвырнулся по стандарту и справочнику - ответа не нашёл. В сети народ инициализируют глобальные вектора недефолтными конструкторами но хз. Ну мало ли - будет над new какая-нибудь надстройка в виде глобального менеджера памяти, которой будет инициализирован после моего цпп модуля, всё - попал в просак.

int *pi = new int;
int main() {return 0;}

Можно много чего делать. И с десятого этажа через окно выйти, вот только какие будут последствия?

Ты можешь глобальные переменные и static члены классов перед main объявлять.

peregrine ★★★★★ ()

Без проблем, это применяется сплошь и рядом в реальных проектах. Правда, обычно это выглядит немного по-другому:

A someObj;

int main() { ...

А уже конструктор A прямо или опосредованно выделяет память в куче. Так что все нормально, если не забывать про static initialization order fiasco.

annulen ★★★★★ ()
Ответ на: комментарий от peregrine

Ты можешь глобальные переменные и static члены классов перед main объявлять.

Это понятно. Хочу разбить прогу на модули, каждый модуль подключать через inclue, в модуле, глобальный объект добавляет в глобальный массив указатель на свой callback.

vector<pointer_to_fn> &get() {
   static vector<pointer_to_fn> ar; return ar;}

//module
void module_fn(...) {}
class Init {
   Init() {get().push_back(module_fn);}
}init;

pavlick ()
Последнее исправление: pavlick (всего исправлений: 2)

будет над new какая-нибудь надстройка в виде глобального менеджера памяти, которой будет инициализирован после моего цпп модуля

Это плохая, негодная реализация new. Вообще лучше глобальные операторы new не переопределять, это чревато многими граблями

annulen ★★★★★ ()
Ответ на: комментарий от pavlick

Ну почему бы нет если стандарт не ограничивает.

Это плохая формулировка в отношении C++.
С++ много в чем тебя не ограничивает, даже от выстрела в ногу. Это фишка C++.

Kroz ★★★★★ ()

Правильная последовательность инициализации глобальных объектов реализуется синглтоном Майерса.

Глобальный new лучше не переопределять. Если ты думаешь, что можешь создать менеджер памяти лучше jemalloc, то ты, скорее всего, фантазер, хотя бывают исключения.

anonymous ()
Ответ на: комментарий от anonymous

Я не собираюсь переопределять new и про синглтоны знаю. Но идея в том, чтобы заполнять глобальный массив (vector c зашитым в него вызовом new) во время инициализации глобальных переменных в подключаемых модулях, в результате отпадёт необходимость вносить какие-то правки в main(), достаточно подключить необходимый модули:

#include "module_1.hh"
//#include "module_2.hh"  // а вот его отключим
#include "module_3.hh"
и все колбэки автоматом попадают в глобальный массив и в последствии дёргаются из главного алгоритма. И вроде как народ дергает new перед main(), но сомнения терзают.

pavlick ()

Технически - можно, практически - может быть брошено исключение и main() даже не запустится, а следовательно у тебя не будет шанса его обработать.

m0rph ★★★★★ ()
Последнее исправление: m0rph (всего исправлений: 2)

В стандарте это где-то в области [basic.start.dynamic] начинается, наверное. Там о динамической инициализации, которая может включать любое выражение, в том числе и с new. Так как для new никакого исключения не сделано, то должно быть можно.

xaizek ★★★★★ ()
Ответ на: комментарий от pavlick

в модуле, глобальный объект добавляет в глобальный массив указатель на свой callback

GlobalFooPrivate.h:

class GlobalFooPrivate ... // decl
GlobalFooPrivate.cpp:
#include "GlobalFooPrivate.h"

GlobalFooPrivate GlobalFoo;

class GlobalFooPrivate ... // impl
GlobalFoo.h:
#include "GlobalFooPrivate.h"

extern GlobalFooPrivate GlobalFoo;
main.cpp (или другой файл, где нужен GlobalFoo):
#include "GlobalFoo.h"

int
main()
{
    GlobalFoo.bar();

    return 0;
}
И пусть модули у него регистрируются. Не?

deep-purple ★★★★★ ()
Ответ на: комментарий от deep-purple

Смотрел, смотрел, но так и не въехал в идею. Может моё косноязычие мешает объяснить то, что мне нужно? Компилируемый пример:

#include <iostream>
#include <vector>
#include <chrono>
#include <thread>
using namespace std;

typedef void(*callback_t)();

vector<callback_t> cb;

// опционально подключаемый модуль----------------------------//
void module_1_cb() {cout << "hello from module 1" << endl;}   //
class Init_module_1 {                                         //
public:                                                       //
   Init_module_1() {cb.push_back(module_1_cb);}               //
}init_module_1;                                               //
//------------------------------------------------------------//

// опционально подключаемый модуль----------------------------//
void module_2_cb() {cout << "hello from module 2" << endl;}   //
class Init_module_2 {                                         //
public:                                                       //
   Init_module_2() {cb.push_back(module_2_cb);}               //
}init_module_2;                                               //
//------------------------------------------------------------//

// главный модуль
int main() {
   while(true) {
      for(callback_t f : cb) {
         f();
      }
      this_thread::sleep_for(1s);
   }
   return 0;
}

Важно: мы может закомментировать любой «опционально подключаемый модуль» и нет необходимости ничего править в main(), это основное, просто #include и доп функционал автоматом добавляется в прогу. ЗЫ: в общем никто особо не возражает против new в GV, так и поступлю наверное. Спасибо.

pavlick ()
Ответ на: комментарий от pavlick

так и не въехал в идею

А я тебя понял правильно. Инклюдим GlobalFoo.h в каждый свой модуль если они в разных файлах. При ините, каждый модуль добавляет свой калбяк в этот глобал (твой вектор или даже несколько векторов под разные типы калбяков внутри него). Теперь мейн, тоже знающий о глобале, крутит в цикле всё, что туда понадобавлялось.

закомментировать

И не только, например опции при сборке.

new

Что-то я его в твоем примере так и не увидел. Ну да ладно, у меня тоже пример без new.

deep-purple ★★★★★ ()
Ответ на: комментарий от deep-purple

Так мы говорим об одном и том же.

Что-то я его в твоем примере так и не увидел. Ну да ладно, у меня тоже пример без new.

Ну когда мы пихаем в вектор колбэки, он ведь память выделяет.

pavlick ()