· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ZEN —› cpp: #define macro()

Посл.отвђт Сообщенiе


Дата: Сен 28, 2004 17:06:58

Привет всем!

Вопросы по большй части к тем, что много пишет / писАл на С и использует при этом возможности препроцессора.

Предположим, определены такие макросы:
#define f(a)    f(2 * (a))

Далее, где-то есть вызов:
f(f(z))

Это будет разложено в:
f(2 * (f(2 * (z))))

Главный смысл здесь - макрос вызавается как бы рекурсивно.

Вопрос: насколько часто подобные вещи встречаются / использубтся в реальных ситуациях?

Я сам со сложными конструкциями не сталкивался, и насколько знаю, использование их не приветствуется.
Действительно ли это так?


Например, такой "простой" код ввергает препроцессор LCC в глубокую задумчивость
(из которой он выходит лишь тогда, когда заканчивается память у ОС):
#define g(a)
#define t(a)    a

t(g)(0)


Ещё, может быть есть у кого примеры каких-то реальнах макросов, которые сложнее, чем то, что можно встретить где-нибудь в инклудах у микрософта.
"Громоздкие" конструкции не интересуют - дело именно во всевозможных трюках со скобочками и т.п.


Заренее благодарен.


ЗЫ
Всё это нужно для тестирования / написания препроцессора имеющего некоторую совместимость с сишным.

ЗЫЫ
Руководствуюсь ansi_iso_iec_14882_1998.pdf - описание там несколько расплывчатое, но как я понял более точного / подробного нет?


Дата: Сен 28, 2004 18:51:31

На Си писал много :) Но макросами по возможности не пользовался. У Голуба много написано. В С++ вместо макросов надо юзать темплейты. Вот, собственно, и все размышления.


Дата: Сен 28, 2004 20:50:06

На С писал, можно даже, наверное, сказать что 3 года это много, но большие или немножко нестандартные макросы не использовал, ибо изврат.


Дата: Сен 28, 2004 21:18:06

Да, я примерно такой ответ и ожидал :)

Но препроцессор этот планируется использовать не с Си, а с ассемблером, а поэтому без макросов не обойтись.
Основная цель - возможность использовать готовые include, где куча всяких простых макроопределений, вроде
#define SW_HIDE             0
#define CreateDialogA(hInstance, lpName, hWndParent, lpDialogFunc) \
CreateDialogParamA(hInstance, lpName, hWndParent, lpDialogFunc, 0L)


От полной совместимости я отказался, так как необходима возможность "многоразового" переопределения макросов.
Из-за этого появляются некоторые проблемы, например:
#define f(a)    f(2 * (a))

f(f(z))

у меня преобразуется в:

f(2 * (f(z)))
(из-за того, что макросы можно переопределять, некоторые проблемы с выходом из рекурсии получаются при строгом следовании Си стандарту)

Сейчас для решения проблемы у меня можно сделать так
#define f(a)    f(2 * (a))
#define f(a)    f(2 * (a))

f(f(z))
тогда всё будет нормально развёрнуто (т.е. как в Си).

То есть, при написании своих макросов всё эти нюансы можно учитывать (it's not a bug, it's a feature :-), но хочется достичь наилучшего компромисса в совместимости с теми макросами, которые уже есть.

Поэтому у меня размышления длятся несколько дольше :)


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.169