Является ли хорошей идеей применить базовые макросы для упрощения кода в большом проекте? - PullRequest
8 голосов
/ 20 апреля 2010

Я работаю над базовой библиотекой c ++ уже некоторое время, и у меня есть множество идей, которые могут действительно упростить процесс написания кода и управления им. Одним из них является концепция введения некоторых макросов, чтобы упростить операторы, которые появляются очень часто, но немного сложнее, чем это необходимо.

Например, я придумал этот базовый макрос для упрощения наиболее распространенного типа цикла for:

#define loop(v,n) for(unsigned long v=0; v<n; ++v)

Это позволит вам заменить те неуклюжие циклы, которые вы видите так:

for (int i = 0; i < max_things; i++)

С чем-то гораздо более простым в написании и даже немного более эффективным:

loop (i, max_things)

Хорошо ли использовать такие соглашения? Есть ли проблемы, с которыми вы можете столкнуться с различными типами компиляторов? Будет ли это слишком запутанным для кого-то незнакомого с макросом (ами)?

Ответы [ 9 ]

26 голосов
/ 20 апреля 2010

ИМХО это вообще плохая идея. Вы по сути меняете хорошо известный и понятный синтаксис на что-то свое. Вскоре вы можете обнаружить, что заново изобрели язык . :)

2 голосов
/ 20 апреля 2010

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

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

2 голосов
/ 20 апреля 2010

Я думаю, что вы привели один веский аргумент против этого макроса в вашем примере использования. Вы изменили тип итератора цикла с int на unsigned long. Это не имеет никакого отношения к тому, сколько печатать вы хотите, так зачем менять?

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

2 голосов
/ 20 апреля 2010

Нет, не очень хорошая идея.


  int max = 23;
  loop(i, ++max)...

Однако, неплохо бы преобразовать часто используемый код в повторно используемые компоненты, а затем повторно использовать вместо копирования. Вы должны сделать это путем написания функций, похожих на стандартные алгоритмы, такие как std :: find (). Например:


template < typename Function >
void loop(size_t count, Function f)
{
  for (size_t i = 0; i < count, ++i) f();
}

Это гораздо более безопасный подход:


int max = 23;
loop(++max, boost::bind(....));
2 голосов
/ 20 апреля 2010

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

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

И поскольку вероятность того, что вы будете иметь дело с кодом, практически равна нулю, если вы надеетесь, что код станет библиотекой, предназначенной не только для вашего личного использования, - тогда я бы согласился с don «т .

1 голос
/ 20 апреля 2010

Как правило, избавление от циклов for - хорошая идея, но замена их макросами - нет. Вместо этого я бы внимательно посмотрел на стандартные библиотечные алгоритмы.

0 голосов
/ 20 апреля 2010

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

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

0 голосов
/ 20 апреля 2010

Стив Джессоп делает хорошую мысль. Макросы имеют свое применение. Если бы я мог разъяснить его утверждения, я бы зашел так далеко, что сказал бы, что аргумент за или против макроса сводится к «Это зависит». Если вы делаете свои макросы без тщательного обдумывания, вы рискуете усложнить жизнь будущим мастерам. С другой стороны, использование библиотеки wxWidgets требует использования предоставленных библиотекой макросов для соединения вашего кода с библиотекой графического интерфейса. В этом случае макросы снижают входной барьер для использования библиотеки, поскольку магия, внутренности которой не имеют отношения к пониманию того, как работать с библиотекой, скрыта от пользователя. В этом случае пользователь избавлен от необходимости понимать то, что ему действительно не нужно знать, и может утверждать, что это «хорошее» использование макросов. Кроме того, wxWidgets четко документирует, как эти макросы должны использоваться. Поэтому убедитесь, что то, что вы скрываете, не должно быть понято кем-то, кто входит.

Или, если это только для вашего использования, нокаутируйте себя.

0 голосов
/ 20 апреля 2010

Вопрос в том, откуда вы получаете свою ценность. Действительно ли ввод этих 15 дополнительных символов в циклы замедляет развитие? Возможно нет. Если у вас есть несколько строк запутанных, неизбежных шаблонов, появляющихся повсюду, то вы можете и должны искать способы избежать повторения, такие как создание полезных функций, очистка иерархий классов или использование шаблонов.

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

...