2011-01-01 4 views
1

код имеет ряд следующих разделов:Макросы препроцессора: как вставить аргументы?

int filter; 
#ifdef INPUTFILTER_FOO 
LOG4CXX_DEBUG(log, "FOO filter used"); 
     filter = F_FOO; 
#endif 

Они используются несколько раз в коде (используются для обеспечения ввода/вывода, Поддержка потоков и т.д. для всех конфигураций тестирования), Circa они необходимы для отладки, но сделайте код выглядеть суровым, захотите заменить его макросами, по одному для каждого пространства имен category_type.

Итак, хочет расширить следующее:

< MACROSTUFFBAZ(log2, stuff, "BAZ") - текстовая часть является уникальной для каждого класса, поэтому она должна быть включена в макросе тоже.

к:

#ifdef INPUTSTUFF_BAZ 
    LOG4CXX_DEBUG(log2, "BAZ stuff used"); 
    stuff = S_BAZ; 
#endif 

Для определения макросов, планируют использовать это:

debug.hpp:

#ifdef INPUTSTUFF_BAZ 
    #define MACROSTUFFBAZ ... 
    #else 
    #define MACROSTUFFBAZ 
    .. no code! 
    #endif 
    #endif 

(по крайней мере, это даст четкое представление о вещах, в настоящее время проходят проверку, не видя их вокруг кода)

+1

Вы не знаете о 'filter = F_FOO' и' stuff = S_BAZ': когда это 'S_'? Когда это 'F_'? Это зависит от макропараметров? – icecrime

+0

@icecrime, это просто другие макроопределенные значения (префикс имени файла, счетчики, задержки и т. Д.). Они не зависят от параметров, а определяются макросом. –

ответ

3

Вот моя попытка, хотя я не на 100% конечно, если он работает, потому что я не могу проверить его прямо сейчас, а также разные компиляторы обрабатывают макросы препроцессора немного по-другому. Но я думаю, что что-то вроде этого работает, по крайней мере, в визуальной студии.

В принципе, вы должны использовать вспомогательный макрос, чтобы преобразовать параметр в строку. А во-вторых, вы можете использовать ## для конкатенации идентификаторов:

#define PRMTOSTR_HLPR(x) #x 
#define PRMTOSTR(x) PRMTOSTR_HLPR(x) 

#ifdef INPUTSTUFF_BAZ 
    #define MACROSTUFFBAZ(A,B,C) \ 
    LOG4CXX_DEBUG(A, PRMTOSTR(C)" stuff used"); \ 
    B = S_##C; 
#else 
    #define MACROSTUFFBAZ(A,B,C) 
#endif 

//used like this: 
MACROSTUFFBAZ(log2, stuff, BAZ) 

редактировать: Помощник макросъемки на самом деле здесь не нужен, так что вы можете просто положить #C непосредственно в определении MACROSTUFFBAZ.

+0

'# x' правильный, но вам не нужен вспомогательный макрос. Вы можете просто поместить '# C' непосредственно во второй макрос. Пространства между строками также прекрасны, они будут конкатенированы одинаково. –

+0

Вы правы. Я помнил, что для чего-то необходим двойной уровень косвенности, но для цитирования значений других макросов: http://stackoverflow.com/questions/216875/in-macros/217181#217181 – Timo

Смежные вопросы