Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> макросы в плюсовом коде, макросы в плюсовом коде 
:(
    Опции темы
 
Макросы в плюсах
Пользуюсь [ 16 ]  [47.06%]
Не пользуюсь [ 13 ]  [38.24%]
Предпочитаю вместо макросов использовать ... (свой вариант в каментах) [ 5 ]  [14.71%]
А что это такое? [ 0 ]  [0.00%]
Всего проголосовавших: 34
В этом опросе возможен один вариант ответа
Гости не могут голосовать 
Sahab
Дата 19.4.2012, 17:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 1.9.2009

Репутация: нет
Всего: 3



Код

// вставка ожидающего или смотрящего игру
#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
  ...
}


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

Это сообщение отредактировал(а) Sahab - 19.4.2012, 17:49
PM MAIL   Вверх
boostcoder
Дата 19.4.2012, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



предпочитаю вместо макросов использовать функции/шаблонные_функции.

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


Это сообщение отредактировал(а) boostcoder - 19.4.2012, 17:49
PM WWW   Вверх
serghd
Дата 19.4.2012, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



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


Это сообщение отредактировал(а) serghd - 19.4.2012, 17:43
PM MAIL   Вверх
Sahab
Дата 19.4.2012, 17:43 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 1.9.2009

Репутация: нет
Всего: 3



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

По поводу этого я в принципе молчу, потому что если аргументироваться подобным, то можно такого говнеца наваять...
PM MAIL   Вверх
mes
Дата 19.4.2012, 17:55 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



макросы только там где необходимо

Это сообщение отредактировал(а) mes - 19.4.2012, 17:55


--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 19.4.2012, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



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

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

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

PM WWW   Вверх
serghd
Дата 19.4.2012, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



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

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

чтобы говнеца не ваять надо знать "ПОЧЕМУ то, а не это". Если объяснений нет, или они неубедительны, то "почему бы и нет".
PM MAIL   Вверх
Sahab
Дата 19.4.2012, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 151
Регистрация: 1.9.2009

Репутация: нет
Всего: 3



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

Добавлено через 5 минут и 48 секунд
Если для Вас неубедительным является "небезопасность" макросов. Что ж - вперед, и надеюсь не напоретесь на херню.
PM MAIL   Вверх
serghd
Дата 19.4.2012, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



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

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

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

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



Это сообщение отредактировал(а) serghd - 19.4.2012, 20:15
PM MAIL   Вверх
bsa
Дата 20.4.2012, 00:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



жуть. зачем делать этот большой код встраиваемым всегда? Почему нельзя было поручить это компилятору, создав шаблон/функцию?
PM   Вверх
borisbn
Дата 20.4.2012, 09:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



ответил
Цитата
Предпочитаю вместо макросов использовать ...

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

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

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


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Earnest
Дата 20.4.2012, 09:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



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

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


--------------------
...
PM   Вверх
serghd
Дата 20.4.2012, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



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

Код

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);


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

Это сообщение отредактировал(а) serghd - 20.4.2012, 20:04
PM MAIL   Вверх
boostcoder
Дата 20.4.2012, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



конечно правильней. ибо не зависит от контекста.
к тому же, код переусложнен.
PM WWW   Вверх
serghd
Дата 20.4.2012, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 5.10.2009

Репутация: нет
Всего: нет



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

в чём конкретно?
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0872 ]   [ Использовано запросов: 24 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.