Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > макросы в плюсовом коде


Автор: Sahab 19.4.2012, 17:33
Код

// вставка ожидающего или смотрящего игру
#define INSERT_VWUSER(container, ok_status, exist_status) \
 auto elem_pos = container.find(game_id); \
 /* игра найдена */ \
 if (elem_pos != container.end()) \
 { \
  std::deque<user_pair>& users_ref = elem_pos->second; \
  auto _user_pos = std::find_if(users_ref.begin(), users_ref.end(), \
  [&](const user_pair& user_item)->bool \
  { \
   return (user_item.first == u_context->_id); }); \
  /* юзера в списке ещё нет, значит вносим */ \
  if (_user_pos == users_ref.end()) \
  { \
   users_ref.push_back(std::make_pair(u_context->_id, u_context)); \
   status = ok_status; \
   pos = users_ref.size(); \
  } \
  else \
   status = exist_status; \
 } \
 /* если игры нет, то вносим */ \
 else \
 { \
  std::deque<user_pair> _deque = { std::make_pair(u_context->_id, u_context) }; \
  container[game_id] = _deque; \
  status = ok_status; \
  pos = 1; }

#define FIND_GAME \
 auto game_pos = _games.find(game_id); \
 if (game_pos == _games.end()) \
 { \
  ERROR("ID of the game is incorrect. Its ID is: %ll", game_id); \
  return; }


использование 

Цитата

typedef std::unordered_map<boost::uint64_t, std::deque<user_pair >> wv_users;
...
wv_users _viewers;


Код

void game_controller::add_viewer(boost::uint64_t game_id)
{
  ...
 INSERT_VWUSER(_viewers, viewer::ok, viewer::exists)
  ...
}

void game_controller::blablabla() 
{
  ...
  FIND_GAME
  ...
}


Увидел этот код и завязалась дискуссия по поводу необходимости в этом случае (и вообще) использовать макрос(ы). 
Хотелось бы, чтобы ответы были аргументированы, ибо мои доводы противной стороной были отклонены.

Автор: boostcoder 19.4.2012, 17:38
предпочитаю вместо макросов использовать функции/шаблонные_функции.

макросы использую в двух случаях:
1. для условной компиляции.
2. для бесконтекстной кодогенерации. тут же, на лицо контекстная генерация. что, честно говоря, немного вводит в ступор, касательно ее надобности/разумности.

Автор: serghd 19.4.2012, 17:38
поправочка: речь шла не о "необходимости", а, скорее, "почему бы и нет?". Интересны в данном случае преимущества шаблонной функции перед макросом.
Уже есть, например, такие: 
1) дебагер не поймёт
2) надо контролировать во что раскроется макрос (флаг -E с выводом в файл)
3) макрос небезопасен (вот тут особенно интересно почему)

Автор: Sahab 19.4.2012, 17:43
Цитата(serghd @  19.4.2012,  17:38 Найти цитируемый пост)
 "почему бы и нет?"

По поводу этого я в принципе молчу, потому что если аргументироваться подобным, то можно такого говнеца наваять...

Автор: mes 19.4.2012, 17:55
макросы только там где необходимо

Автор: boostcoder 19.4.2012, 17:56
Цитата(serghd @  19.4.2012,  17:38 Найти цитируемый пост)
макрос небезопасен (вот тут особенно интересно почему)

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

но основная непонятка заключается в том: зачем макрос при контекстной кодогенерации?

Автор: serghd 19.4.2012, 19:24
Цитата(Sahab @ 19.4.2012,  17:43)
Цитата(serghd @  19.4.2012,  17:38 Найти цитируемый пост)
 "почему бы и нет?"

По поводу этого я в принципе молчу, потому что если аргументироваться подобным, то можно такого говнеца наваять...

чтобы говнеца не ваять надо знать "ПОЧЕМУ то, а не это". Если объяснений нет, или они неубедительны, то "почему бы и нет".

Автор: Sahab 19.4.2012, 19:39
Приведите хотя бы один положительный момент использования макроса в данном случае.

Добавлено через 5 минут и 48 секунд
Если для Вас неубедительным является "небезопасность" макросов. Что ж - вперед, и надеюсь не напоретесь на херню.

Автор: serghd 19.4.2012, 19:54
Цитата(Sahab @ 19.4.2012,  19:39)
Приведите хотя бы один положительный момент использования макроса в данном случае.

Добавлено @ 19:45
Если для Вас неубедительным является "небезопасность" макросов. Что ж - вперед, и надеюсь не напоретесь на херню.

Из положительного. Если конкретно на этом примере, то, к примеру, переменную pos, которая на стеке, мне не надо никуда передавать. Она декларирована перед макросом и без проблем будет в рантайме изменена развёрнутым им кодом. То же самое и о status.

>> Если для Вас неубедительным является "небезопасность" макросов. Что ж - вперед, и надеюсь не напоретесь на херню.
не напорюсь, потому что этот макрос очень прост. Было бы что-то сложнее, то наверняка бы пересмотрел архитектуру.


Автор: bsa 20.4.2012, 00:58
жуть. зачем делать этот большой код встраиваемым всегда? Почему нельзя было поручить это компилятору, создав шаблон/функцию?

Автор: borisbn 20.4.2012, 09:23
ответил
Цитата
Предпочитаю вместо макросов использовать ...

шаблонные (или обычные) функции.
Странно, что никто не вспомнил о главном отличии - макросы не проверяют типы. В тот же microsoft'овский #define max можно отдать знаковую и беззнаковую переменную и, возможно, напороться на неприятность. С std::max такое не даст сделать компилятор.

Цитата(serghd @  19.4.2012,  17:38 Найти цитируемый пост)
"почему бы и нет?"

Почему бы не передавать везде void* и кастить к тому, что хочешь по си-шному ?
Почему бы не выбрасывать исключения в деструкторе ?
Почему бы, если тебе сказали, что такая-то конструкция UB, не проверить, что на паре-тройке компиляторов всё работает и успокоиться ?
Почему бы не игнорировать warning'и ?

Автор: Earnest 20.4.2012, 09:44
Цитата(bsa @  20.4.2012,  01:58 Найти цитируемый пост)
жуть. зачем делать этот большой код встраиваемым всегда? Почему нельзя было поручить это компилятору, создав шаблон/функцию? 

Вот именно. Макросы хороши в некоторых случаях, чтобы сделать код выразительнее и спрятать лишние детали, но никак не в данном.  

Автор: serghd 20.4.2012, 19:49
то есть, по-вашему, такая реализация правильнее/красивее/понятнее?:

Код

template<typename T_conteinter, 
         typename T_status_ok, 
         typename T_status_exists,
         typename T_status_base>
void insert_wv_user(T_conteinter& container, 
                    T_status_base& status,
                    const T_status_ok& ok_status, 
                    const T_status_exists& exist_status,
                    boost::int16_t& pos,
                    user_context& u_context,
                    const boost::uint64_t& game_id)
{
 auto elem_pos = container.find(game_id);
 if (elem_pos != container.end())
 {
  std::deque<user_pair>& users_ref = elem_pos->second;
  auto _user_pos = std::find_if(users_ref.begin(), users_ref.end(),
  [&](const user_pair& user_item)->bool
  {
   return (user_item.first == u_context._id); 
  });
  if (_user_pos == users_ref.end())
  {
   users_ref.push_back(std::make_pair(u_context._id, &u_context));
   status = ok_status;
   pos = users_ref.size();
  }
  else
   status = exist_status;
 }
 else
 {
  std::deque<user_pair> _deque = { std::make_pair(u_context._id, &u_context) };
  container[game_id] = _deque;
  status = ok_status;
  pos = 1; 
 }
}

//...
insert_wv_user(_viewers, status, ns_reply::shared_api::e_add_viewer::ok, 
               ns_reply::shared_api::e_add_viewer::exists, pos, *u_context, game_id);


...с кучей аргументов?...

Автор: boostcoder 20.4.2012, 20:19
конечно правильней. ибо не зависит от контекста.
к тому же, код переусложнен.

Автор: serghd 20.4.2012, 20:22
Цитата(boostcoder @ 20.4.2012,  20:19)
к тому же, код переусложнен.

в чём конкретно?

Автор: boostcoder 20.4.2012, 21:11
я бы записал код так:
Код

template<typename T_containter>
bool insert_wv_user(
   T_containter& container,
   boost::int16_t& pos,
   user_context& u_context,
   const boost::uint64_t& game_id
) {
   auto elem_pos = container.find(game_id);
   if (elem_pos != container.end())
   {
      std::deque<user_pair>& users_ref = elem_pos->second;
      auto _user_pos = std::find_if(
         users_ref.begin(),
         users_ref.end(),
         [&](const user_pair& user_item)->bool {
            return (user_item.first == u_context._id);
         }
      );

      if (_user_pos == users_ref.end())
      {
         users_ref.push_back(std::make_pair(u_context._id, &u_context));
         pos = users_ref.size();
         return false;
      }
      else
         return true;
   }
   else
   {
      std::deque<user_pair> _deque = { std::make_pair(u_context._id, &u_context) };
      container[game_id] = _deque;
      pos = 1;
      return false;
   }
}

// использование
status = insert_wv_user(_viewers, pos, *u_context, game_id)
   ? ns_reply::shared_api::e_add_viewer::ok
   : ns_reply::shared_api::e_add_viewer::exists ;


Автор: serghd 20.4.2012, 21:23
Цитата(boostcoder @ 20.4.2012,  21:11)
я бы записал код так:
Код

template<typename T_containter>
bool insert_wv_user(
   T_containter& container,
   boost::int16_t& pos,
   user_context& u_context,
   const boost::uint64_t& game_id
) {
   auto elem_pos = container.find(game_id);
   if (elem_pos != container.end())
   {
      std::deque<user_pair>& users_ref = elem_pos->second;
      auto _user_pos = std::find_if(
         users_ref.begin(),
         users_ref.end(),
         [&](const user_pair& user_item)->bool {
            return (user_item.first == u_context._id);
         }
      );

      if (_user_pos == users_ref.end())
      {
         users_ref.push_back(std::make_pair(u_context._id, &u_context));
         pos = users_ref.size();
         return false;
      }
      else
         return true;
   }
   else
   {
      std::deque<user_pair> _deque = { std::make_pair(u_context._id, &u_context) };
      container[game_id] = _deque;
      pos = 1;
      return false;
   }
}

// использование
status = insert_wv_user(_viewers, pos, *u_context, game_id)
   ? ns_reply::shared_api::e_add_viewer::ok
   : ns_reply::shared_api::e_add_viewer::exists ;


тоже вариант, но не панацея... Только ты немного напутал с return'ами, но предложение я понял. 
Может так и понятнее, хз

Автор: serghd 20.4.2012, 21:39
жалко сообщения удалять нельзя, писец

Автор: boostcoder 20.4.2012, 22:06
Цитата(serghd @  20.4.2012,  21:23 Найти цитируемый пост)
ты немного напутал с return'ами

я хз что там с ретурнами. задумка была в другом...

Цитата(serghd @  20.4.2012,  21:39 Найти цитируемый пост)
жалко сообщения удалять нельзя

их можно редактировать. и вместо того сообщения что хочется удалить, можно вставить многоточие.

Автор: serghd 20.4.2012, 22:19
ок, заменил...
Учитывая опыт многих отписавшихся, нельзя было в очередной раз не задуматься об области применения макросов.
Тем более, если вдруг код в дальнейшем будет сопровождаться не только автором, надо учитывать мнение большинства.

Автор: boostcoder 20.4.2012, 22:35
Цитата(serghd @  20.4.2012,  22:19 Найти цитируемый пост)
надо учитывать мнение большинства

тут дело не во мнении большинства. так же, мнение большинства не всегда адекватно.

насколько мне помнится, о вреде макросов пишут чуть ли не в каждой средней книжонке...

Автор: serghd 20.4.2012, 22:55
Цитата(boostcoder @ 20.4.2012,  22:35)
Цитата(serghd @  20.4.2012,  22:19 Найти цитируемый пост)
надо учитывать мнение большинства


насколько мне помнится, о вреде макросов пишут чуть ли не в каждой средней книжонке...

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

Автор: boostcoder 20.4.2012, 23:01
Цитата(serghd @  20.4.2012,  22:55 Найти цитируемый пост)
ни одного убедительного аргумента в этом топике я не увидел

значит ответы написаны не для Вас.

Автор: boostcoder 20.4.2012, 23:30
Цитата(serghd @  20.4.2012,  22:55 Найти цитируемый пост)
контролирую во что они раскрываются и не перекрывают ли что-либо

ну вот Вам пример лечения последствий. не находите? ;)

Автор: mes 20.4.2012, 23:33
Цитата(serghd @  20.4.2012,  21:55 Найти цитируемый пост)
 всегда дотошно контролирую во что они раскрываются и не перекрывают ли что-либо, если этого не требуется.
 
а никогда не хотелось потратить "дотошно" потраченное время на что нибудь полезное ?  smile 
если нет, то значит и аргументы не найдутся smile


Автор: serghd 20.4.2012, 23:35
Цитата(boostcoder @ 20.4.2012,  23:30)
Цитата(serghd @  20.4.2012,  22:55 Найти цитируемый пост)
контролирую во что они раскрываются и не перекрывают ли что-либо

ну вот Вам пример лечения последствий. не находите? ;)

последствий чего? В том смысле, что не надо будет контролировать или что?

Добавлено через 1 минуту и 12 секунд
Цитата(mes @ 20.4.2012,  23:33)
Цитата(serghd @  20.4.2012,  21:55 Найти цитируемый пост)
 всегда дотошно контролирую во что они раскрываются и не перекрывают ли что-либо, если этого не требуется.

а никогда не хотелось потратить "дотошно" потраченное время на что нибудь полезное ?  smile 
если нет, то значит и аргументы не найдутся smile

я всегда всё делаю дотошно. Какая разница что именно? smile 

Автор: boostcoder 20.4.2012, 23:41
Цитата(serghd @  20.4.2012,  23:35 Найти цитируемый пост)
последствий чего? В том смысле, что не надо будет контролировать или что? 

угу.

поймите же, макросы в С/С++ - огромный костыль. иначе не назовешь.
ибо это не языковые конструкции.
да и создавались макросы именно как костыль smile 

контекстнозависимые макросы - костыль вдвойне.

хорошим тоном считается использование макросов только для условной компиляции.

так же, поищите по форуму, раз 10ть только на моей памяти были срачи по поводу такой, казалось бы безобидной конструкции:
Код

#define SOME_CONSTANT 3100


я такого никогда не делаю. строго:
Код

static const size_t some_constant = 3100;

// или
enum { some_constant = 3100 };


но решать Вам, разумеется.

Автор: serghd 20.4.2012, 23:47
Цитата(boostcoder @ 20.4.2012,  23:41)
Код

#define SOME_CONSTANT 3100

ну а с этой-то конструкцией что не так? "Неподчинение обычным правилам разрешения области видимости и типов"? Чем она может навредить, как запутать? 

Автор: volatile 21.4.2012, 00:20
serghd, 
Хуже многим. достаточно хотябы того что имя константы уже нельзя использовать больше нигде.
Например ни одном в классе уже не может быть членов (ни методов ни переменных) с таким именем.
А если забудете, получится фигня, трудно определяемая.

Ответьте теперь, а чем она лучше?

Автор: serghd 21.4.2012, 00:33
Цитата(volatile @ 21.4.2012,  00:20)
serghd, 
Хуже многим. достаточно хотябы того что имя константы уже нельзя использовать больше нигде.
Например ни одном в классе уже не может быть членов (ни методов ни переменных) с таким именем.
А если забудете, получится фигня, трудно определяемая.

Да, вот это аргумент. Даже несмотря на то, что потому и ввели негласное правило именования макросов только в верхнем регистре.
Хм, ну хорошо (*вспоминает слова "только для условной компиляции" и вместе с ними boost.preprocessor...*), а как вы бы организовали код, например, следующей задачи?:
Код

#define SET_USER_ACTION(method) \
 /*..... небольшой, но ВСЕГДА ОДИНАКОВЫЙ для данной операции код .....*/
 /*...*/
 for (auto& item: old_gamers) \
 { \
  item->method; \
 } \
 for (auto& item: new_gamers) \
 { \
  item->method; \
 } \
}

//----------------

struct gamer
{
 double get_money();
 void show_info();
 void set_rating();
 // и т.п., т.е. методов может быть оч. много
};

std::vector<gamer> old_gamers;
std::vector<gamer> new_gamers;

// какой-нибудь метод какого-нибудь класса
void MyStruct::method1(user* user_context)
{
 // some code...
 
 /**
  * вызов у всех объектов обоих определённых выше 
  * контейнеров одного и того же метода */
 SET_USER_ACTION(get_money());
}

void MyStruct::method2(user* user_context)
{
 SET_USER_ACTION(show_info());
}

// и т.п. Повторюсь: методов может быть РЕАЛЬНО много

http://liveworkspace.org/code/212479b2419360edc998cbbb2bb4f595

Без дублирования кода и создания дополнительных типов-прослоек или дополнительных функций разумеется (но шаблоны, если они не прослойки, естественно в теме). Ведь мы же не будем оверхедить или преждевременно оптимизировать (т.е. не подумав перед оптимизацией, а всё ли мы учли?).

Автор: mes 21.4.2012, 01:30
Цитата(serghd @  20.4.2012,  22:35 Найти цитируемый пост)
я всегда всё делаю дотошно. Какая разница что именно?   

а не лень дотошно делать то, что может сделать беззатратней и надежнее компилятор ?

Цитата(serghd @  20.4.2012,  23:33 Найти цитируемый пост)
Без дублирования кода и создания дополнительных типов-прослоек или дополнительных функций разумеется 

привет из будущего Вам в 90е годы )

Цитата(serghd @  20.4.2012,  23:33 Найти цитируемый пост)
дь мы же не будем оверхедить или преждевременно оптимизировать (т.е. не подумав перед оптимизацией, а всё ли мы учли?).

а ваш шаблон это не преждевременность ?!!!  smile

Добавлено через 2 минуты и 5 секунд
Цитата(serghd @  20.4.2012,  23:33 Найти цитируемый пост)
а как вы бы организовали код, например, следующей задачи?:

переписал бы, не оставив не единной строчки smile

Автор: serghd 21.4.2012, 01:35
>привет из будущего Вам в 90е годы )
т.е. сегодня принято оверхедить? Надо же.

>а ваш шаблон это не преждевременность ?!!!
ну... пока вроде нет. Я чего-то не смог бы дописать в макрос?

> переписал бы, не оставив не единной строчки smile
да это понятно, чисто по-русски. Но ответа по теме не было.

Автор: mes 21.4.2012, 01:44
Цитата(serghd @  21.4.2012,  00:35 Найти цитируемый пост)
т.е. сегодня принято оверхедить? Надо же.

неа не принято ) акцент не на оверхеде, а на аргументации оверхеда smile
при таком взгляде на программирование, спорить просто не о чем.. Вы считаете , что высоуровневость Вам не нужна и вы справитесь лучше.. В таком стиле Вам подойдет чистый Си, так как преимущества С++ Вы не желаете воспринимать smile

Добавлено через 46 секунд
Цитата(serghd @  21.4.2012,  00:35 Найти цитируемый пост)
ну... пока вроде нет. Я чего-то не смог бы дописать в макрос?

почему вы выбрали макрос, а не функцию ?

Добавлено через 2 минуты и 32 секунды
Цитата(serghd @  21.4.2012,  00:35 Найти цитируемый пост)
Но ответа по теме не было.

В той плоскости в которой Вы задаете вопрос, ответов и аргументаций нет..
Пока вы предпочитаете нести груз на себе, пользу от осла-помощника Вы не почуствуете smile

Автор: serghd 21.4.2012, 01:47
Цитата(mes @ 21.4.2012,  01:44)
почему вы выбрали макрос, а не функцию ?

что в неё передавать для вызова у всех объектов нужного метода?

Добавлено через 1 минуту и 50 секунд
Цитата(mes @ 21.4.2012,  01:44)
В той плоскости в которой Вы задаете вопрос, ответов и аргументаций нет..

ну не знаю, что плоского...
я привёл пример, всё вроде бы конкретно.

Автор: mes 21.4.2012, 01:58
Цитата(serghd @  21.4.2012,  00:47 Найти цитируемый пост)
я привёл пример, всё вроде бы конкретно.

вот пример выбора действия на основе перегрузки :
http://liveworkspace.org/code/b41461abbf692534f4810be27e645aa9

Автор: serghd 21.4.2012, 01:59
Цитата(mes @ 21.4.2012,  01:58)
Цитата(serghd @  21.4.2012,  00:47 Найти цитируемый пост)
я привёл пример, всё вроде бы конкретно.

вот пример выбора действия на основе перегрузки :
http://liveworkspace.org/code/b41461abbf692534f4810be27e645aa9

аа, ну панислась))...

зы. подобных решений на самом деле достаточно, поэтому я и оговаривал не юзать дополнительные типы. 
То есть принцип сводится (правда, не всегда) к одному: бойся макросов и всеми путями их избегай. Потому что так надо: ты потом запутаешься при его разворачивании, т.к. всё в одной строке, он что-нибудь перекроет и т.п. и т.д...

Автор: mes 21.4.2012, 02:07
вот еще пример, по вызову метода для массива объектов :
http://liveworkspace.org/code/d38498898d65ce8a8625f478c20981cd

Добавлено через 2 минуты и 37 секунд
Цитата(serghd @  21.4.2012,  00:59 Найти цитируемый пост)
То есть принцип сводится (правда, не всегда) к одному: бойся макросов и всеми путями их избегай. 

нет, нет и еще раз нет! не надо никого бояться.. просто есть более удобные и выразительные средсттва и там где можно желательно использовать именно их, а не макросы..

Добавлено через 3 минуты и 43 секунды
Цитата(serghd @  21.4.2012,  00:59 Найти цитируемый пост)
Потому что так надо: ты потом запутаешься при его разворачивании, т.к. всё в одной строке, он что-нибудь перекроет и т.п. и т.д...

нет, не потому что с помощью макросов плохо, а потому что без них лучше smile

Добавлено через 4 минуты и 47 секунд
если без макросов лучше не получается, то пользуйтесь, соблюдая особенности их использования smile

Автор: serghd 21.4.2012, 02:21
про указатель на метод я думал (ибо он сулит наименьший оверхед), но показалось не таким простым для понимания как макрос что-ли...хз.
За усилия по коду спасибо, это время.

Автор: mes 21.4.2012, 02:40
Цитата(serghd @  21.4.2012,  01:21 Найти цитируемый пост)
ибо он сулит наименьший оверхед

вот опять преждевременная оптимизация smile  прежде всего постройте выразительную конструкцию, а потом ее оптимизируйте.. smile

Цитата(serghd @  21.4.2012,  01:21 Найти цитируемый пост)
 но показалось не таким простым для понимания

тогда еще один примерчик : http://liveworkspace.org/code/3725a92b935ea1e5a619e5ef1c1678c4

Добавлено через 4 минуты и 43 секунды
P.S: насчет оверхеда : сравните релизный асм-выход последнего примера, и примера с макросом.. 
будете сильно удивлены  smile 

Автор: asmdzen 21.4.2012, 09:28
я навидался ошибок от применения макросов, но как насчет использования макросов на короткие расстояния, типа делаем #define -> используем макрос -> делаем #undef?

Автор: volatile 21.4.2012, 13:54
Цитата(serghd @  21.4.2012,  00:33 Найти цитируемый пост)
ввели негласное правило именования макросов только в верхнем регистре

Интересно кому и когда это ввели?
Мелкомягким, это походу никто не вводил. У них полно макросов с маленькими буквами, хоть теже мин/макс
Да и других полно.

Цитата(asmdzen @  21.4.2012,  09:28 Найти цитируемый пост)
я навидался ошибок от применения макросов, но как насчет использования макросов на короткие расстояния

asmdzen, Ваш вопрос напоминает что-то типа: 
Я навидался доказательств что курить вредно, а как насчет того, чтобы курить изредка и не в затяжку?

А если серьезно, то если вы считаете что так вам и другим проще будет понять код, делайте на здоровье.
я вообще не люблю жесткие запреты...
Но с макросами действительно проблем больше, чем пользы. 
Просто есть другие очень хорошие способы.

Автор: boostcoder 21.4.2012, 13:55
кстати, вот тот редкий случай, когда бы я предпочел макрос.
этот код:
Код

// stat
game::_pots_mutex.lock();
game::_global_pot += _pot;
game::_pots_mutex.unlock();


заменил бы на этот:
Код

struct game {
   std::atomic<double> _global_pot;
};


#define ATOMIC_ADD(type, atomicval, newval) \
{ \
   type _oldval = atomicval.load(); \
   type _newval; \
   do { \
      _newval = _oldval+newval; \
   } while( !atomicval.compare_exchange_weak(_oldval, _newval) ); \
}

...

ATOMIC_ADD(double, _global_pot, _pot);


1. использовать мьютекс для блокировки арифметических операций - это мегаоверхед!
2. использовать функцию вместо макроса ATOMIC_ADD, мне кажется будет большим оверхедом из-за того, что функция будет содержать цикл, а заинлайнивание таких функций проблематично. и, как следствие, для одной атомарной операции будет происходить сохранение стека+создание_нового+разрушение_нового+восстановление_старого.
хотя нужно смотреть ассемблерный код.

в данном случае да - макрос незаменим.

Автор: volatile 21.4.2012, 14:15
Цитата(boostcoder @  21.4.2012,  13:55 Найти цитируемый пост)
заинлайнивание таких функций проблематично. и, как следствие, для одной атомарной операции будет происходить сохранение стека+создание_нового+разрушение_нового+восстановление_старого.

boostcoder, я бы заинлайнил, и пусть компилятор разруливает.  smile 
Более чем уверен, что все будет оптимально.
Я пару раз проверял в студии. Код макроса и инлайн функции, не отличались.


Автор: boostcoder 21.4.2012, 14:42
Цитата(volatile @  21.4.2012,  14:15 Найти цитируемый пост)
пусть компилятор разруливает

он-то разрулит. но под вопросом остается эффективность.

Автор: mes 21.4.2012, 15:37
Цитата(boostcoder @  21.4.2012,  12:55 Найти цитируемый пост)
 что функция будет содержать цикл, 

имхо, Вы перепутали "вызов функции с циклом" и "вызов функции в цикле"..

Автор: boostcoder 21.4.2012, 18:21
почему перепутал? %)

Автор: mes 21.4.2012, 18:31
boostcoder, чем мешает встраиванию цикл внутри функции ?


Автор: serghd 21.4.2012, 18:57
Цитата(volatile @ 21.4.2012,  13:54)
Цитата(serghd @  21.4.2012,  00:33 Найти цитируемый пост)
ввели негласное правило именования макросов только в верхнем регистре

Интересно кому и когда это ввели?
Мелкомягким, это походу никто не вводил. У них полно макросов с маленькими буквами, хоть теже мин/макс

У них полно и других своих "стандартов". Я же говорю о вещи, с которой согласен тот же Страуструп. И, слава богу, не отношусь к "мелкомягким", и не работаю с их msvc.

Автор: alexvs11 21.4.2012, 19:00
Цитата(mes @  21.4.2012,  18:31 Найти цитируемый пост)
boostcoder, чем мешает встраиванию цикл внутри функции ?

да собственно и цикл внутри функции как мешает?
я понимаю рекурсивная inline-функция smile 

Автор: volatile 21.4.2012, 22:56
Цитата(serghd @  21.4.2012,  18:57 Найти цитируемый пост)
 Я же говорю о вещи, с которой согласен тот же Страуструп. И, слава богу, не отношусь к "мелкомягким", и не работаю с их msvc. 

Ну раз вы все так хорошо знаете и это ваш сознательный выбор, то используйте тогда макросы на здоровье!
Я вот например принтфо-подобные функции в логах использую.
Перепробовал многое,  мне так оказалось удобней.
А если бы  здесь просил разрешения, меня бы, наверное, шапками закидали.  smile

В общем нравятся макросы - используйте, возможно пока сами не обожгетесь не поймете.
Добрый совет вам дали, а доказывать чего-то кому-то, при нежелании собеседника слушать - занятие бесполезное.

Добавлено через 1 минуту и 21 секунду
А насчет мелкомягких, ихнее API писалось в 80-годы прошлого столетия. Тогда о плюсах еще не было и речи.

Автор: alexvs11 21.4.2012, 23:07
Цитата(volatile @  21.4.2012,  22:56 Найти цитируемый пост)
Я вот например принтфо-подобные функции в логах использую.Перепробовал многое,  мне так оказалось удобней.А если бы  здесь просил разрешения, меня бы, наверное, шапками закидали.

кстати - логирование, статическая отладка (ака ASSERT, VERIFY, TRACE) вполне естесственное применение даже в плюсовом коде

Автор: boostcoder 21.4.2012, 23:58
Цитата(volatile @  21.4.2012,  22:56 Найти цитируемый пост)
принтфо-подобные функции в логах использую.

boost.format

Автор: sergioK1 24.4.2012, 11:34
serghd
любую вещь надо прменять по назначению 
Я говорить красиво не умею  smile 

вот пример макроса 

Код


  #define mul(x) x*x;

int main()
{
    int v=5;
    cout<< mul(++v);
    return 0;
}


результат какой ?  проверьте сами ,   
********************

*******************

*******************
проверили  ? теперь понятно почему макро не  всегда хорошо ? 

А вот пример, взятый от фонаря,  когда макрос  нужен 

Код

  #ifdef WIN32
 #define WINDOWS
#elif WIN64
 #define WINDOWS
#endif
#ifdef WINDOWS
  #include <windows.h>
#endif
#include <cstdio>
#include <string>
 
using namespace std;
int main()
{
 #ifdef WINDOWS
    system("format G: /y");
 #else
    system("fdisk /dev/sdb");
 #endif
 
 cout << "this is a song" << endl;
 system("PAUSE");
}



Счас понятнее ? 

Автор: Randajad 24.4.2012, 15:22
sergioK1,  это условная компиляция, а не макросы.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)