Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.78/86: Рейтинг темы: голосов - 86, средняя оценка - 4.78
0 / 0 / 0
Регистрация: 05.01.2010
Сообщений: 9

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

08.01.2010, 03:29. Показов 19447. Ответов 115

Студворк — интернет-сервис помощи студентам
После прочтения про директиву препроцессора define возник вопрос по поводу применения define, как функции:
C++
1
#define QQ (q) (q^q)
Можно же улучшить читаемость кода, используя вместо функций именно директиву define. Или у данного использования макроса есть подводные камки какие-то? Да и объем кода в разы сократиться, так как для define будет достаточно всего-навсего одной строчки.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
08.01.2010, 03:29
Ответы с готовыми решениями:

Чем так плох чипсет P31?
Здрасти! Скажите чем так плох этот чипсет?

чем плох mysql_query
Просматривал вакансию на пхп juniora наткнулся на такое требование "В коде нет и намека на mysql_query("SELECT * ...." я...

Чем плох uCoz?
Добрый день! Хотел бы услышать объективные мнения специалистов, на тему "Почему юКоз нельзя использовать для создания полноценного...

115
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
08.01.2010, 03:53
это макросы препроцессора.
на стадии их "расширения" не производится проверка компилятором. потому, отыскать ошибки, связанные с макросами, крайне сложно.
и вообще, это плохой тон.

а для случая который вы привели, прекрасно подходит функция.
1
 Аватар для Gravity
577 / 571 / 65
Регистрация: 29.01.2009
Сообщений: 1,274
08.01.2010, 03:54
Цитата Сообщение от ertyuo Посмотреть сообщение
Можно же улучшить читаемость кода, используя вместо функций именно директиву define.
Для читабельности нет особой разницы между обычной функцией и макросом. Макросы делают для того, чтобы не создавался кадр стека (как при вызове функции), за счет этого код выполняется несколько быстрее. Но необходимость в макросах отпала с появлением inline-функций, которые есть и в C++ и в C99.
2
0 / 0 / 0
Регистрация: 05.01.2010
Сообщений: 9
08.01.2010, 12:13  [ТС]
Спасибо за ответы, про inline не знал... Как-то кроме программных файлов - conio.h не видел его применения, да и в учебниках особенного упоминания...
0
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
08.01.2010, 13:54
Цитата Сообщение от niXman Посмотреть сообщение
и вообще, это плохой тон.

Вообще-то макросы - плохой тон как раз из-за этих их неприятных особенностей.
Основные минусы - неудобство в отладке, засорение глобального пространства имён, возможность возникновения всяких неприятных непредвиденных эффектов. Например, в приведённом в открывающем посте примере человек, написавший QQ(7) будет долго и упорно думать над непонятными ошибками. А когда догадается посмотреть результат работы препроцессора, к его неприятному изумлению найдёт на месте QQ(7) текст (q) (q^q)(7). Пробел после QQ, видите ли.
А если он и уберёт пробел, то получит интересные, но неправильные результаты на вызове вроде QQ(5+7). А если кто-то случайно позарится на такое же имя для своей функции, имея такое объявление где-то в своих заголовках, получит массу интересных ощущений при попытке разрыть непонятные еггоги.
1
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
08.01.2010, 14:04
значит для быстроты:
C++
1
#define FOR(i,a,b) for (int i(a),_b(b); i < _b; ++i)
это плохой тон?
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
08.01.2010, 14:10
ertyuo, почитай тут https://www.cyberforum.ru/faq/thread55559.html
Конкретно ответ на твой вопрос - разделы 3.3.2 и 3.3.3
0
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
08.01.2010, 14:29
outoftime, да, плохой. Точнее говоря, не "плохой тон", а "плохой стиль".
В конце концов, это же программирование, а не ловля блох, тут спешка вообще вредна. А если не устраивает скорость, с которой печатаются буковки, бери денежку и иди на поклон к Владимиру Владимировичу Шахиджаняну - так всяко лучше будет.
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
08.01.2010, 14:39
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
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
08.01.2010, 14:43
outoftime, ради спорта, конечно, можно и плохим стилем пользоваться. Но если собираешься писать программы, которыми реально будут пользоваться люди, лучше приучать себя к хорошему стилю. А уж если собираешься писать достаточно большие и сложные программы, все эти "маленькие спортивные хитрости" лучше забыть как страшный сон.
1
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
08.01.2010, 14:48
Nick Alte, "Преждевременная оптимизация - корень всех зол." Д. Кнут
я обычно юзаю два екземпляра кода)
0
Эксперт С++
 Аватар для odip
7176 / 3234 / 82
Регистрация: 17.06.2009
Сообщений: 14,164
08.01.2010, 14:50
Всем кто считает что define и макросы - это плохой тон или стиль.
Откройте стандартные include-файлы для любого компилятора в любой системе !
Вы офигеете от того кол-ва макросов, которое там используется !

А еще есть некоторые случае когда использование макросов повышает читаемость текста
outoftime, в посте #6 привел один из примеров
0
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
08.01.2010, 14:53
При всей противоречивости этих высказываний outoftime, оба они имеют одинаково мало отношения к обсуждаемой теме.
odip, это тяжёлое наследие царского режима, которое до сих пор должно быть совместимым с Си. А вообще, я и так офигеваю, когда у меня какой-нибудь метод называется аналогично одной из тысяч функций, определённых в Windows через макросы. Бывают отдельные случаи, плюсы макросов перевешивают минусы, но не так уж и часто. Да и в таких случаях лучше изолировать опасные участки.
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
08.01.2010, 14:59
Цитата Сообщение от odip Посмотреть сообщение
А еще есть некоторые случае когда использование макросов повышает читаемость текста
с этим согласен, особенно когда надо впихнуть несколько слогаемых, или что-бы не писать find(a.begin(),a.end(),'6')-a.begin() в форе несколько раз, лично я юзаю только для быстроты, но если мне легче расписать (для понимания) тогда расписываю, как по мне, дефайны плохо воспринимаются, но они сами наклёвываются, когда пишешь сто раз одно и тоже..
0
MCSD: APP BUILDER
 Аватар для IT_Exp
8795 / 1074 / 104
Регистрация: 17.06.2006
Сообщений: 32,602
08.01.2010, 15:05
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
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
08.01.2010, 15:11
не, не хочу стандартную функцию юзать, я из-за того что она не то вернула контест был запорол..
я лучше дефайны юзать буду..
0
1 / 0 / 0
Регистрация: 22.10.2015
Сообщений: 6
22.10.2015, 11:27
Кликните здесь для просмотра всего текста
Немножко старую тему отрыл. Но это вечно и может быть полезно другим. Почитал тут и на хабре, ничего убедительного, кроме
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. Может макросы стоит добавить сюда.
0
22.10.2015, 11:36

Не по теме:

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

0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
22.10.2015, 11:38
Цитата Сообщение от LynXzp Посмотреть сообщение
Точно так же как и функции. (Функции можно обернуть в класс? Макросы - в файл. #undefine нет смысла использовать - делает макароны из файла)
Функции можно обернуть в namespace.
Макросы ради констант в С++ использовать не стоит, либо const переменная, либо enum.
1
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
22.10.2015, 11:43
LynXzp, тебе надо дать медаль почётного археолога
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.10.2015, 11:43
Помогаю со студенческими работами здесь

Чем плох goto?
Вы хотели интересных тем? Так вот, я на днях думал, а почему goto так плох, и решил загуглить, почему же? Я нагуглил вот эту статью и, мне...

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

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

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

Чем плох ProBuilder (Unity3D)?
Мне советовали не использовать ProBuilder, а моделить в какой-нибудь проге - текстурить и потом эспортировать в юнити. Аргументировали это...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru