| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > макросы в плюсовом коде |
| Автор: Sahab 19.4.2012, 17:33 | ||||||
использование
Увидел этот код и завязалась дискуссия по поводу необходимости в этом случае (и вообще) использовать макрос(ы). Хотелось бы, чтобы ответы были аргументированы, ибо мои доводы противной стороной были отклонены. |
| Автор: boostcoder 19.4.2012, 17:38 |
| предпочитаю вместо макросов использовать функции/шаблонные_функции. макросы использую в двух случаях: 1. для условной компиляции. 2. для бесконтекстной кодогенерации. тут же, на лицо контекстная генерация. что, честно говоря, немного вводит в ступор, касательно ее надобности/разумности. |
| Автор: serghd 19.4.2012, 17:38 |
| поправочка: речь шла не о "необходимости", а, скорее, "почему бы и нет?". Интересны в данном случае преимущества шаблонной функции перед макросом. Уже есть, например, такие: 1) дебагер не поймёт 2) надо контролировать во что раскроется макрос (флаг -E с выводом в файл) 3) макрос небезопасен (вот тут особенно интересно почему) |
| Автор: Sahab 19.4.2012, 17:43 |
По поводу этого я в принципе молчу, потому что если аргументироваться подобным, то можно такого говнеца наваять... |
| Автор: mes 19.4.2012, 17:55 |
| макросы только там где необходимо |
| Автор: boostcoder 19.4.2012, 17:56 |
как уже было замечено - непонятно во что он раскроется. если же он раскроется так, что код все равно скомпилируется но при этом логика будет нарушена - то тут начнется самое интересное. и дебагер тут не поможет, ибо препроцессор весь код развернет в одну строку %) второе - макросы работают заменой одних токенов, другими. можно с легкостью пересечь имена аргументов макроса с именами переменных в коде, и опять, имеем вынос моцга. но основная непонятка заключается в том: зачем макрос при контекстной кодогенерации? |
| Автор: serghd 19.4.2012, 19:24 | ||
чтобы говнеца не ваять надо знать "ПОЧЕМУ то, а не это". Если объяснений нет, или они неубедительны, то "почему бы и нет". |
| Автор: Sahab 19.4.2012, 19:39 |
| Приведите хотя бы один положительный момент использования макроса в данном случае. Добавлено через 5 минут и 48 секунд Если для Вас неубедительным является "небезопасность" макросов. Что ж - вперед, и надеюсь не напоретесь на херню. |
| Автор: serghd 19.4.2012, 19:54 | ||
Из положительного. Если конкретно на этом примере, то, к примеру, переменную pos, которая на стеке, мне не надо никуда передавать. Она декларирована перед макросом и без проблем будет в рантайме изменена развёрнутым им кодом. То же самое и о status. >> Если для Вас неубедительным является "небезопасность" макросов. Что ж - вперед, и надеюсь не напоретесь на херню. не напорюсь, потому что этот макрос очень прост. Было бы что-то сложнее, то наверняка бы пересмотрел архитектуру. |
| Автор: bsa 20.4.2012, 00:58 |
| жуть. зачем делать этот большой код встраиваемым всегда? Почему нельзя было поручить это компилятору, создав шаблон/функцию? |
| Автор: borisbn 20.4.2012, 09:23 | ||
ответил
шаблонные (или обычные) функции. Странно, что никто не вспомнил о главном отличии - макросы не проверяют типы. В тот же microsoft'овский #define max можно отдать знаковую и беззнаковую переменную и, возможно, напороться на неприятность. С std::max такое не даст сделать компилятор. Почему бы не передавать везде void* и кастить к тому, что хочешь по си-шному ? Почему бы не выбрасывать исключения в деструкторе ? Почему бы, если тебе сказали, что такая-то конструкция UB, не проверить, что на паре-тройке компиляторов всё работает и успокоиться ? Почему бы не игнорировать warning'и ? |
| Автор: serghd 20.4.2012, 19:49 | ||
то есть, по-вашему, такая реализация правильнее/красивее/понятнее?:
...с кучей аргументов?... |
| Автор: boostcoder 20.4.2012, 20:19 |
| конечно правильней. ибо не зависит от контекста. к тому же, код переусложнен. |
| Автор: serghd 20.4.2012, 20:22 | ||
в чём конкретно? |
| Автор: boostcoder 20.4.2012, 21:11 | ||
я бы записал код так:
|
| Автор: serghd 20.4.2012, 21:23 | ||||
тоже вариант, но не панацея... Только ты немного напутал с return'ами, но предложение я понял. Может так и понятнее, хз |
| Автор: serghd 20.4.2012, 21:39 |
| жалко сообщения удалять нельзя, писец |
| Автор: boostcoder 20.4.2012, 22:06 |
я хз что там с ретурнами. задумка была в другом... их можно редактировать. и вместо того сообщения что хочется удалить, можно вставить многоточие. |
| Автор: serghd 20.4.2012, 22:19 |
| ок, заменил... Учитывая опыт многих отписавшихся, нельзя было в очередной раз не задуматься об области применения макросов. Тем более, если вдруг код в дальнейшем будет сопровождаться не только автором, надо учитывать мнение большинства. |
| Автор: boostcoder 20.4.2012, 22:35 |
тут дело не во мнении большинства. так же, мнение большинства не всегда адекватно. насколько мне помнится, о вреде макросов пишут чуть ли не в каждой средней книжонке... |
| Автор: serghd 20.4.2012, 22:55 | ||
ни разу не встречал, хотя читал не одну. Только на форумах. Да и ни одного убедительного аргумента в этом топике я не увидел. Т.к. всегда дотошно контролирую во что они раскрываются и не перекрывают ли что-либо, если этого не требуется. |
| Автор: boostcoder 20.4.2012, 23:01 |
значит ответы написаны не для Вас. |
| Автор: boostcoder 20.4.2012, 23:30 |
ну вот Вам пример лечения последствий. не находите? ;) |
| Автор: mes 20.4.2012, 23:33 | ||
а никогда не хотелось потратить "дотошно" потраченное время на что нибудь полезное ? если нет, то значит и аргументы не найдутся |
| Автор: serghd 20.4.2012, 23:35 | ||||||
последствий чего? В том смысле, что не надо будет контролировать или что? Добавлено через 1 минуту и 12 секунд
я всегда всё делаю дотошно. Какая разница что именно? |
| Автор: boostcoder 20.4.2012, 23:41 | ||||||
угу. поймите же, макросы в С/С++ - огромный костыль. иначе не назовешь. ибо это не языковые конструкции. да и создавались макросы именно как костыль контекстнозависимые макросы - костыль вдвойне. хорошим тоном считается использование макросов только для условной компиляции. так же, поищите по форуму, раз 10ть только на моей памяти были срачи по поводу такой, казалось бы безобидной конструкции:
я такого никогда не делаю. строго:
но решать Вам, разумеется. |
| Автор: serghd 20.4.2012, 23:47 | ||||
ну а с этой-то конструкцией что не так? "Неподчинение обычным правилам разрешения области видимости и типов"? Чем она может навредить, как запутать? |
| Автор: volatile 21.4.2012, 00:20 |
| serghd, Хуже многим. достаточно хотябы того что имя константы уже нельзя использовать больше нигде. Например ни одном в классе уже не может быть членов (ни методов ни переменных) с таким именем. А если забудете, получится фигня, трудно определяемая. Ответьте теперь, а чем она лучше? |
| Автор: serghd 21.4.2012, 00:33 | ||||
Да, вот это аргумент. Даже несмотря на то, что потому и ввели негласное правило именования макросов только в верхнем регистре. Хм, ну хорошо (*вспоминает слова "только для условной компиляции" и вместе с ними boost.preprocessor...*), а как вы бы организовали код, например, следующей задачи?:
http://liveworkspace.org/code/212479b2419360edc998cbbb2bb4f595 Без дублирования кода и создания дополнительных типов-прослоек или дополнительных функций разумеется (но шаблоны, если они не прослойки, естественно в теме). Ведь мы же не будем оверхедить или преждевременно оптимизировать (т.е. не подумав перед оптимизацией, а всё ли мы учли?). |
| Автор: mes 21.4.2012, 01:30 | ||||
а не лень дотошно делать то, что может сделать беззатратней и надежнее компилятор ?
привет из будущего Вам в 90е годы )
а ваш шаблон это не преждевременность ?!!! Добавлено через 2 минуты и 5 секунд переписал бы, не оставив не единной строчки |
| Автор: serghd 21.4.2012, 01:35 |
| >привет из будущего Вам в 90е годы ) т.е. сегодня принято оверхедить? Надо же. >а ваш шаблон это не преждевременность ?!!! ну... пока вроде нет. Я чего-то не смог бы дописать в макрос? > переписал бы, не оставив не единной строчки да это понятно, чисто по-русски. Но ответа по теме не было. |
| Автор: mes 21.4.2012, 01:44 |
неа не принято ) акцент не на оверхеде, а на аргументации оверхеда при таком взгляде на программирование, спорить просто не о чем.. Вы считаете , что высоуровневость Вам не нужна и вы справитесь лучше.. В таком стиле Вам подойдет чистый Си, так как преимущества С++ Вы не желаете воспринимать Добавлено через 46 секунд почему вы выбрали макрос, а не функцию ? Добавлено через 2 минуты и 32 секунды В той плоскости в которой Вы задаете вопрос, ответов и аргументаций нет.. Пока вы предпочитаете нести груз на себе, пользу от осла-помощника Вы не почуствуете |
| Автор: serghd 21.4.2012, 01:47 | ||||
что в неё передавать для вызова у всех объектов нужного метода? Добавлено через 1 минуту и 50 секунд
ну не знаю, что плоского... я привёл пример, всё вроде бы конкретно. |
| Автор: mes 21.4.2012, 01:58 |
вот пример выбора действия на основе перегрузки : http://liveworkspace.org/code/b41461abbf692534f4810be27e645aa9 |
| Автор: serghd 21.4.2012, 01:59 | ||
аа, ну панислась))... зы. подобных решений на самом деле достаточно, поэтому я и оговаривал не юзать дополнительные типы. То есть принцип сводится (правда, не всегда) к одному: бойся макросов и всеми путями их избегай. Потому что так надо: ты потом запутаешься при его разворачивании, т.к. всё в одной строке, он что-нибудь перекроет и т.п. и т.д... |
| Автор: mes 21.4.2012, 02:07 | ||||
| вот еще пример, по вызову метода для массива объектов : http://liveworkspace.org/code/d38498898d65ce8a8625f478c20981cd Добавлено через 2 минуты и 37 секунд
нет, нет и еще раз нет! не надо никого бояться.. просто есть более удобные и выразительные средсттва и там где можно желательно использовать именно их, а не макросы.. Добавлено через 3 минуты и 43 секунды
нет, не потому что с помощью макросов плохо, а потому что без них лучше Добавлено через 4 минуты и 47 секунд если без макросов лучше не получается, то пользуйтесь, соблюдая особенности их использования |
| Автор: serghd 21.4.2012, 02:21 |
| про указатель на метод я думал (ибо он сулит наименьший оверхед), но показалось не таким простым для понимания как макрос что-ли...хз. За усилия по коду спасибо, это время. |
| Автор: mes 21.4.2012, 02:40 |
вот опять преждевременная оптимизация тогда еще один примерчик : http://liveworkspace.org/code/3725a92b935ea1e5a619e5ef1c1678c4 Добавлено через 4 минуты и 43 секунды P.S: насчет оверхеда : сравните релизный асм-выход последнего примера, и примера с макросом.. будете сильно удивлены |
| Автор: asmdzen 21.4.2012, 09:28 |
| я навидался ошибок от применения макросов, но как насчет использования макросов на короткие расстояния, типа делаем #define -> используем макрос -> делаем #undef? |
| Автор: volatile 21.4.2012, 13:54 | ||||
Интересно кому и когда это ввели? Мелкомягким, это походу никто не вводил. У них полно макросов с маленькими буквами, хоть теже мин/макс Да и других полно.
asmdzen, Ваш вопрос напоминает что-то типа: Я навидался доказательств что курить вредно, а как насчет того, чтобы курить изредка и не в затяжку? А если серьезно, то если вы считаете что так вам и другим проще будет понять код, делайте на здоровье. я вообще не люблю жесткие запреты... Но с макросами действительно проблем больше, чем пользы. Просто есть другие очень хорошие способы. |
| Автор: boostcoder 21.4.2012, 13:55 | ||||
| кстати, вот тот редкий случай, когда бы я предпочел макрос. этот код:
заменил бы на этот:
1. использовать мьютекс для блокировки арифметических операций - это мегаоверхед! 2. использовать функцию вместо макроса ATOMIC_ADD, мне кажется будет большим оверхедом из-за того, что функция будет содержать цикл, а заинлайнивание таких функций проблематично. и, как следствие, для одной атомарной операции будет происходить сохранение стека+создание_нового+разрушение_нового+восстановление_старого. хотя нужно смотреть ассемблерный код. в данном случае да - макрос незаменим. |
| Автор: volatile 21.4.2012, 14:15 | ||
boostcoder, я бы заинлайнил, и пусть компилятор разруливает. Более чем уверен, что все будет оптимально. Я пару раз проверял в студии. Код макроса и инлайн функции, не отличались. |
| Автор: boostcoder 21.4.2012, 14:42 |
он-то разрулит. но под вопросом остается эффективность. |
| Автор: mes 21.4.2012, 15:37 |
имхо, Вы перепутали "вызов функции с циклом" и "вызов функции в цикле".. |
| Автор: boostcoder 21.4.2012, 18:21 |
| почему перепутал? %) |
| Автор: mes 21.4.2012, 18:31 |
| boostcoder, чем мешает встраиванию цикл внутри функции ? |
| Автор: serghd 21.4.2012, 18:57 | ||||
У них полно и других своих "стандартов". Я же говорю о вещи, с которой согласен тот же Страуструп. И, слава богу, не отношусь к "мелкомягким", и не работаю с их msvc. |
| Автор: alexvs11 21.4.2012, 19:00 |
да собственно и цикл внутри функции как мешает? я понимаю рекурсивная inline-функция |
| Автор: volatile 21.4.2012, 22:56 | ||
Ну раз вы все так хорошо знаете и это ваш сознательный выбор, то используйте тогда макросы на здоровье! Я вот например принтфо-подобные функции в логах использую. Перепробовал многое, мне так оказалось удобней. А если бы здесь просил разрешения, меня бы, наверное, шапками закидали. В общем нравятся макросы - используйте, возможно пока сами не обожгетесь не поймете. Добрый совет вам дали, а доказывать чего-то кому-то, при нежелании собеседника слушать - занятие бесполезное. Добавлено через 1 минуту и 21 секунду А насчет мелкомягких, ихнее API писалось в 80-годы прошлого столетия. Тогда о плюсах еще не было и речи. |
| Автор: alexvs11 21.4.2012, 23:07 | ||
кстати - логирование, статическая отладка (ака ASSERT, VERIFY, TRACE) вполне естесственное применение даже в плюсовом коде |
| Автор: boostcoder 21.4.2012, 23:58 |
boost.format |
| Автор: sergioK1 24.4.2012, 11:34 | ||||
| serghd любую вещь надо прменять по назначению Я говорить красиво не умею вот пример макроса
результат какой ? проверьте сами , ******************** ******************* ******************* проверили ? теперь понятно почему макро не всегда хорошо ? А вот пример, взятый от фонаря, когда макрос нужен
Счас понятнее ? |
| Автор: Randajad 24.4.2012, 15:22 |
| sergioK1, это условная компиляция, а не макросы. |