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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 52, средняя оценка - 4.90
ertyuo
0 / 0 / 0
Регистрация: 05.01.2010
Сообщений: 9
#1

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

08.01.2010, 03:29. Просмотров 7322. Ответов 115

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

Чем плох make? - C++
Дали написать реферат по make файлам и соответственно указать его минусы, а значит сравнить его с такими утилитами как CMake, но для меня...

Чем плох std::map? - C++
std::map ?

Чем плох void main? - C++
Встретил мнение, что void main() - не канон и даже плохо. Но статья древняя, 1996 года, и даже автор открестился, сказав, что для новых...

Чем плох управляемый С++? - C++
Я дико извиняюсь за подобную тему... но дело в том, что мне сегодня задали этот вопрос и, собственно, я не смог на него ответить. Сам я...

Перевести макрос define в функцию - C++
Доброго времени суток. Я тут на днях набросал вот такие макросы для удобства: #define BinSave(Value, Root)\ //Переменная, путь к...

Чем оличается define от const - C++
define A 5; и const a = 5; В первом случае идет замена в предпроцессоре... а во втором? и еще слышал что define оч редко стал...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
niXman
Эксперт C++
3137 / 1449 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
08.01.2010, 03:53 #2
это макросы препроцессора.
на стадии их "расширения" не производится проверка компилятором. потому, отыскать ошибки, связанные с макросами, крайне сложно.
и вообще, это плохой тон.

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

Вообще-то макросы - плохой тон как раз из-за этих их неприятных особенностей.
Основные минусы - неудобство в отладке, засорение глобального пространства имён, возможность возникновения всяких неприятных непредвиденных эффектов. Например, в приведённом в открывающем посте примере человек, написавший QQ(7) будет долго и упорно думать над непонятными ошибками. А когда догадается посмотреть результат работы препроцессора, к его неприятному изумлению найдёт на месте QQ(7) текст (q) (q^q)(7). Пробел после QQ, видите ли.
А если он и уберёт пробел, то получит интересные, но неправильные результаты на вызове вроде QQ(5+7). А если кто-то случайно позарится на такое же имя для своей функции, имея такое объявление где-то в своих заголовках, получит массу интересных ощущений при попытке разрыть непонятные еггоги.
1
outoftime
║XLR8║
510 / 432 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
08.01.2010, 14:04 #6
значит для быстроты:
C++
1
#define FOR(i,a,b) for (int i(a),_b(b); i < _b; ++i)
это плохой тон?
1
Evg
Эксперт CАвтор FAQ
17826 / 6036 / 388
Регистрация: 30.03.2009
Сообщений: 16,567
Записей в блоге: 26
08.01.2010, 14:10 #7
ertyuo, почитай тут http://www.cyberforum.ru/faq/thread55559.html
Конкретно ответ на твой вопрос - разделы 3.3.2 и 3.3.3
0
Nick Alte
Эксперт С++
1638 / 1010 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
08.01.2010, 14:29 #8
outoftime, да, плохой. Точнее говоря, не "плохой тон", а "плохой стиль".
В конце концов, это же программирование, а не ловля блох, тут спешка вообще вредна. А если не устраивает скорость, с которой печатаются буковки, бери денежку и иди на поклон к Владимиру Владимировичу Шахиджаняну - так всяко лучше будет.
0
outoftime
║XLR8║
510 / 432 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
08.01.2010, 14:39 #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) )
0
Nick Alte
Эксперт С++
1638 / 1010 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
08.01.2010, 14:43 #10
outoftime, ради спорта, конечно, можно и плохим стилем пользоваться. Но если собираешься писать программы, которыми реально будут пользоваться люди, лучше приучать себя к хорошему стилю. А уж если собираешься писать достаточно большие и сложные программы, все эти "маленькие спортивные хитрости" лучше забыть как страшный сон.
1
outoftime
║XLR8║
510 / 432 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
08.01.2010, 14:48 #11
Nick Alte, "Преждевременная оптимизация - корень всех зол." Д. Кнут
я обычно юзаю два екземпляра кода)
0
odip
Эксперт С++
7157 / 3297 / 59
Регистрация: 17.06.2009
Сообщений: 14,164
08.01.2010, 14:50 #12
Всем кто считает что define и макросы - это плохой тон или стиль.
Откройте стандартные include-файлы для любого компилятора в любой системе !
Вы офигеете от того кол-ва макросов, которое там используется !

А еще есть некоторые случае когда использование макросов повышает читаемость текста
outoftime, в посте #6 привел один из примеров
0
Nick Alte
Эксперт С++
1638 / 1010 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
08.01.2010, 14:53 #13
При всей противоречивости этих высказываний outoftime, оба они имеют одинаково мало отношения к обсуждаемой теме.
odip, это тяжёлое наследие царского режима, которое до сих пор должно быть совместимым с Си. А вообще, я и так офигеваю, когда у меня какой-нибудь метод называется аналогично одной из тысяч функций, определённых в Windows через макросы. Бывают отдельные случаи, плюсы макросов перевешивают минусы, но не так уж и часто. Да и в таких случаях лучше изолировать опасные участки.
0
outoftime
║XLR8║
510 / 432 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
08.01.2010, 14:59 #14
Цитата Сообщение от odip Посмотреть сообщение
А еще есть некоторые случае когда использование макросов повышает читаемость текста
с этим согласен, особенно когда надо впихнуть несколько слогаемых, или что-бы не писать find(a.begin(),a.end(),'6')-a.begin() в форе несколько раз, лично я юзаю только для быстроты, но если мне легче расписать (для понимания) тогда расписываю, как по мне, дефайны плохо воспринимаются, но они сами наклёвываются, когда пишешь сто раз одно и тоже..
0
Rififi
2359 / 1054 / 44
Регистрация: 03.05.2009
Сообщений: 2,656
08.01.2010, 15:05 #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);

короче говоря, если ты только точно не знаешь что делаешь - не используй макросы.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.01.2010, 15:05
Привет! Вот еще темы с ответами:

#define работает не так, как ожидается - C++
Здравствуйте. Подскажите, пожалуйста, почему в таком случае некорректно использовать #define: switch (kind) { case 1: ...

#define sqr(a) (a)*(a) - зачем так много скобок? - C++
#define sqr(a) ((a)*(a)) такие вопросы: 1) Зачем ((a)*(a)) так много скобок? (если можно,объяснить доступным языком) 2) почему,...

Объясните, в чем суть директив #ifndef/#define/#endif - C++
Не понял в чем суть директив: #ifndef .. #define.. #endifОбъясните пожалуйста..это как - то связано с хедерами, но вот как ??

Что это за макрос? И с чем его едят? - C++
Есть две строки. С первой вроде разобрался, поправьте если не совсем. Из книги Лафоре ООП (реализация консольной графики). #ifndef...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
08.01.2010, 15:05
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru