cpp: #define macro()

Тема в разделе "WASM.ZEN", создана пользователем S_T_A_S_, 28 сен 2004.

  1. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Привет всем!



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



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


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


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


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



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



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

    Действительно ли это так?





    Например, такой "простой" код ввергает препроцессор LCC в глубокую задумчивость

    (из которой он выходит лишь тогда, когда заканчивается память у ОС):
    Код (Text):
    1. #define g(a)
    2. #define t(a)    a
    3.  
    4. t(g)(0)




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

    "Громоздкие" конструкции не интересуют - дело именно во всевозможных трюках со скобочками и т.п.





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





    ЗЫ

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



    ЗЫЫ

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

    volodya wasm.ru

    Публикаций:
    0
    Регистрация:
    22 апр 2003
    Сообщения:
    1.169
    На Си писал много :) Но макросами по возможности не пользовался. У Голуба много написано. В С++ вместо макросов надо юзать темплейты. Вот, собственно, и все размышления.
     
  3. NoName

    NoName New Member

    Публикаций:
    0
    Регистрация:
    1 авг 2004
    Сообщения:
    1.229
    На С писал, можно даже, наверное, сказать что 3 года это много, но большие или немножко нестандартные макросы не использовал, ибо изврат.
     
  4. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Да, я примерно такой ответ и ожидал :)



    Но препроцессор этот планируется использовать не с Си, а с ассемблером, а поэтому без макросов не обойтись.

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




    От полной совместимости я отказался, так как необходима возможность "многоразового" переопределения макросов.

    Из-за этого появляются некоторые проблемы, например:
    Код (Text):
    1. #define f(a)    f(2 * (a))
    2.  
    3. f(f(z))
    4.  
    5. у меня преобразуется в:
    6.  
    7. f(2 * (f(z)))
    (из-за того, что макросы можно переопределять, некоторые проблемы с выходом из рекурсии получаются при строгом следовании Си стандарту)



    Сейчас для решения проблемы у меня можно сделать так
    Код (Text):
    1. #define f(a)    f(2 * (a))
    2. #define f(a)    f(2 * (a))
    3.  
    4. f(f(z))
    тогда всё будет нормально развёрнуто (т.е. как в Си).



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



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