Форум программистов, компьютерный форум CyberForum.ru

Чем же макрос define так плох? - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 52, средняя оценка - 4.90
ertyuo
0 / 0 / 0
Регистрация: 05.01.2010
Сообщений: 6
08.01.2010, 03:29     Чем же макрос define так плох? #1
После прочтения про директиву препроцессора define возник вопрос по поводу применения define, как функции:
C++
1
#define QQ (q) (q^q)
Можно же улучшить читаемость кода, используя вместо функций именно директиву define. Или у данного использования макроса есть подводные камки какие-то? Да и объем кода в разы сократиться, так как для define будет достаточно всего-навсего одной строчки.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.01.2010, 03:29     Чем же макрос define так плох?
Посмотрите здесь:

Объясните, в чем суть директив #ifndef/#define/#endif C++
C++ Чем оличается define от const
Чем плох C++
C++ В чем ошибка? что не так?
#define работает не так, как ожидается C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
niXman
Эксперт C++
 Аватар для niXman
3133 / 1445 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
08.01.2010, 03:53     Чем же макрос define так плох? #2
это макросы препроцессора.
на стадии их "расширения" не производится проверка компилятором. потому, отыскать ошибки, связанные с макросами, крайне сложно.
и вообще, это плохой тон.

а для случая который вы привели, прекрасно подходит функция.
Gravity
 Аватар для Gravity
556 / 550 / 39
Регистрация: 29.01.2009
Сообщений: 1,274
08.01.2010, 03:54     Чем же макрос define так плох? #3
Цитата Сообщение от ertyuo Посмотреть сообщение
Можно же улучшить читаемость кода, используя вместо функций именно директиву define.
Для читабельности нет особой разницы между обычной функцией и макросом. Макросы делают для того, чтобы не создавался кадр стека (как при вызове функции), за счет этого код выполняется несколько быстрее. Но необходимость в макросах отпала с появлением inline-функций, которые есть и в C++ и в C99.
ertyuo
0 / 0 / 0
Регистрация: 05.01.2010
Сообщений: 6
08.01.2010, 12:13  [ТС]     Чем же макрос define так плох? #4
Спасибо за ответы, про inline не знал... Как-то кроме программных файлов - conio.h не видел его применения, да и в учебниках особенного упоминания...
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
08.01.2010, 13:54     Чем же макрос define так плох? #5
Цитата Сообщение от niXman Посмотреть сообщение
и вообще, это плохой тон.

Вообще-то макросы - плохой тон как раз из-за этих их неприятных особенностей.
Основные минусы - неудобство в отладке, засорение глобального пространства имён, возможность возникновения всяких неприятных непредвиденных эффектов. Например, в приведённом в открывающем посте примере человек, написавший QQ(7) будет долго и упорно думать над непонятными ошибками. А когда догадается посмотреть результат работы препроцессора, к его неприятному изумлению найдёт на месте QQ(7) текст (q) (q^q)(7). Пробел после QQ, видите ли.
А если он и уберёт пробел, то получит интересные, но неправильные результаты на вызове вроде QQ(5+7). А если кто-то случайно позарится на такое же имя для своей функции, имея такое объявление где-то в своих заголовках, получит массу интересных ощущений при попытке разрыть непонятные еггоги.
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
08.01.2010, 14:04     Чем же макрос define так плох? #6
значит для быстроты:
C++
1
#define FOR(i,a,b) for (int i(a),_b(b); i < _b; ++i)
это плохой тон?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16833 / 5254 / 323
Регистрация: 30.03.2009
Сообщений: 14,145
Записей в блоге: 26
08.01.2010, 14:10     Чем же макрос define так плох? #7
ertyuo, почитай тут http://www.cyberforum.ru/faq/thread55559.html
Конкретно ответ на твой вопрос - разделы 3.3.2 и 3.3.3
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
08.01.2010, 14:29     Чем же макрос define так плох? #8
outoftime, да, плохой. Точнее говоря, не "плохой тон", а "плохой стиль".
В конце концов, это же программирование, а не ловля блох, тут спешка вообще вредна. А если не устраивает скорость, с которой печатаются буковки, бери денежку и иди на поклон к Владимиру Владимировичу Шахиджаняну - так всяко лучше будет.
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
08.01.2010, 14:39     Чем же макрос define так плох? #9
Nick Alte, ты о спортивном програмировании слышал?

Добавлено через 4 минуты
ertyuo, в твоем коде сть недочет:
C++
1
#define QQ (q) (q^q)
если я возьму q = 5 - все ок, а если q = a*b+vs.size()-1 - тут у тебя будут проблемы, пиши
C++
1
#define QQ(q) ( (q)  ^ (q) )
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
08.01.2010, 14:43     Чем же макрос define так плох? #10
outoftime, ради спорта, конечно, можно и плохим стилем пользоваться. Но если собираешься писать программы, которыми реально будут пользоваться люди, лучше приучать себя к хорошему стилю. А уж если собираешься писать достаточно большие и сложные программы, все эти "маленькие спортивные хитрости" лучше забыть как страшный сон.
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
08.01.2010, 14:48     Чем же макрос define так плох? #11
Nick Alte, "Преждевременная оптимизация - корень всех зол." Д. Кнут
я обычно юзаю два екземпляра кода)
odip
Эксперт C++
 Аватар для odip
7225 / 3287 / 58
Регистрация: 17.06.2009
Сообщений: 14,165
08.01.2010, 14:50     Чем же макрос define так плох? #12
Всем кто считает что define и макросы - это плохой тон или стиль.
Откройте стандартные include-файлы для любого компилятора в любой системе !
Вы офигеете от того кол-ва макросов, которое там используется !

А еще есть некоторые случае когда использование макросов повышает читаемость текста
outoftime, в посте #6 привел один из примеров
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
08.01.2010, 14:53     Чем же макрос define так плох? #13
При всей противоречивости этих высказываний outoftime, оба они имеют одинаково мало отношения к обсуждаемой теме.
odip, это тяжёлое наследие царского режима, которое до сих пор должно быть совместимым с Си. А вообще, я и так офигеваю, когда у меня какой-нибудь метод называется аналогично одной из тысяч функций, определённых в Windows через макросы. Бывают отдельные случаи, плюсы макросов перевешивают минусы, но не так уж и часто. Да и в таких случаях лучше изолировать опасные участки.
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
08.01.2010, 14:59     Чем же макрос define так плох? #14
Цитата Сообщение от odip Посмотреть сообщение
А еще есть некоторые случае когда использование макросов повышает читаемость текста
с этим согласен, особенно когда надо впихнуть несколько слогаемых, или что-бы не писать find(a.begin(),a.end(),'6')-a.begin() в форе несколько раз, лично я юзаю только для быстроты, но если мне легче расписать (для понимания) тогда расписываю, как по мне, дефайны плохо воспринимаются, но они сами наклёвываются, когда пишешь сто раз одно и тоже..
Rififi
 Аватар для Rififi
2330 / 1045 / 43
Регистрация: 03.05.2009
Сообщений: 2,656
08.01.2010, 15:05     Чем же макрос define так плох? #15
ertyuo,

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

с развитием алгоритмов оптимизации в компиляторах использование define вместо функций потеряло смысл. а вот проблем огрести можно.

функции помогают создавать более защищённый и безопасный код. (если конечно руки не из жопы растут - тут уж ничего не поможет)

я уж и не говорю о классическом случае:

#define MIN(a,b) ((a) < (b) ? (a) : (b))
int i=10, j=20;

MIN(i++, j--);

например с макросом возможна вот такая потенциальная кривизна:
int i = ...
unsigned j = ...;
MIN(i, j);

а со встроенной функцией - будет ошибка компиляции
std::min(i, j);

короче говоря, если ты только точно не знаешь что делаешь - не используй макросы.
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
08.01.2010, 15:11     Чем же макрос define так плох? #16
не, не хочу стандартную функцию юзать, я из-за того что она не то вернула контест был запорол..
я лучше дефайны юзать буду..
LynXzp
1 / 0 / 0
Регистрация: 22.10.2015
Сообщений: 6
22.10.2015, 11:27     Чем же макрос define так плох? #17
Кликните здесь для просмотра всего текста
Немножко старую тему отрыл. Но это вечно и может быть полезно другим. Почитал тут и на хабре, ничего убедительного, кроме
MIN(a++,b++);
За это отдельное спасибо - по моему мнению, пока единственный случай когда макросы действительно сливают воду.
Но вот задумался отдать заказчику программу (представляет собой библиотеку и небольшой пример ее применения, изменятся будет только пример и в большой переростать не будет). Хотелось бы чтобы заказчику, как далекому от программирования человеку былобы проще указывать цвета не в RGB числами, а их человеческими названиями.

Язык С99 (99 потому что определения переменных можно ставить где угодно, а так 89). Задача: программирование микроконтроллеров.

Буду говорить в большей степени о #define constA 3 чем о макросах-функциях, это ведь тоже макросы, не смотря на мнение отдельного автора на хабре. На том же хабре была целая тема как на ++ уйти от дефайна константы в сложном случае, только потому что 'макросы - зло'.

Интересует как на счет констант.
C
1
2
3
4
#define clRed 0xff0000
#define clGreen 0x00ff00
........... over9000
WriteText(clRed,"bla-bla")
Просто считается ли это дурным тоном в академическом мире и мире сферического программирования на С/С++?
(В практическом смысле меня уже мало в чем можно переубедить, но не хочу нарушать ничьего чувства прекрасного)

Дефайны можно спрятать в отдельный файл. Но терзают сомнения, опять этот 'дурной тон'. А константы это издевательство, они же будут занимать память все вне зависимости от использования. (Особенно в микроконтроллерах заметно, хотя вовсе не кретично, но уж точно расходовать память на право и на лево - дурной тон.)

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

Кликните здесь для просмотра всего текста
Вообще первый раз вижу что были проблемы из-за того что кто-то не обернул скобочки. Это же в каждом учебнике написано на той же странице что и макросы. ИМНО это не минус. Минус в том что нужно ставить скобочки и их не должен ставит препроцессор по стандарту.

int i = ...
unsigned j = ...;
MIN(i, j);
а со встроенной функцией - будет ошибка компиляции
std::min(i, j);
Ну это только в С++.

засорение глобального пространства имён
Точно так же как и функции. (Функции можно обернуть в класс? Макросы - в файл. #undefine нет смысла использовать - делает макароны из файла)

Макрос в заголовке? Ну вы же не даете на экспорт функции которые не хотите чтобы были импортированными всеми.

И еще ни #inline ни -О3 совершенно не означают что функция будет встроена. По крайней мере для avr-gcc
.

P.S. мой личный (точнее с другом придумали) трюк позволяющий и видеть числа на месте констант в коде и 'никаких чисел в коде'
#define MAX_LENGTH_50 50
А при изменении переименовать. Не оч удобно если во многих файлах используется константа, но какая красота - у меня все константы теперь такие, и никакого копроммиса. (Ну clRed разве что и то это для заказчика)

P.P.S. люблю подшучивать: детям нельзя делить на ноль, секс и использовать goto. Может макросы стоит добавить сюда.
gru74ik
22.10.2015, 11:36
  #18

Не по теме:

Цитата Сообщение от Nick Alte Посмотреть сообщение
иди на поклон к Владимиру Владимировичу Шахиджаняну
Отстой. Бесячий тип. У меня рвотный рефлекс на него. Stamina - лучший клавиатурный тренажёр, имхо.

ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
22.10.2015, 11:38     Чем же макрос define так плох? #19
Цитата Сообщение от LynXzp Посмотреть сообщение
Точно так же как и функции. (Функции можно обернуть в класс? Макросы - в файл. #undefine нет смысла использовать - делает макароны из файла)
Функции можно обернуть в namespace.
Макросы ради констант в С++ использовать не стоит, либо const переменная, либо enum.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.10.2015, 11:43     Чем же макрос define так плох?
Еще ссылки по теме:

C++ Палиндромы. Плох ли мой код?
Чем так отличается язык с++ от других языков программирования C++
C++ #define sqr(a) (a)*(a) - зачем так много скобок?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
gru74ik
Модератор
 Аватар для gru74ik
3122 / 1348 / 167
Регистрация: 20.02.2013
Сообщений: 3,867
Записей в блоге: 18
22.10.2015, 11:43     Чем же макрос define так плох? #20
LynXzp, тебе надо дать медаль почётного археолога
Yandex
Объявления
22.10.2015, 11:43     Чем же макрос define так плох?
Ответ Создать тему

Метки
#define
Опции темы

Текущее время: 11:30. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru