#ifdef внутри макроса

Возможный дубликат:
#ifdef внутри #define

Как мне успешно использовать символ "#" внутри макроса? Он кричит, когда я делаю что-то подобное:

#define DO(WHAT)        \
#ifdef DEBUG        \                           
  MyObj->WHAT()         \       
#endif              \

person JasonGenX    schedule 30.08.2011    source источник


Ответы (5)


Вы не можете этого сделать. Вам нужно сделать что-то вроде этого:

#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT) do { } while(0)
#endif

do { } while(0) избегает пустых операторов. См., Например, этот вопрос .

person Roger Lipscombe    schedule 30.08.2011
comment
Значит, с пустым оператором у меня могут возникнуть проблемы с некоторыми компиляторами C ++? Мое приложение кроссплатформенное, OSX, Windows и Ubuntu. Это безопасно? - person JasonGenX; 30.08.2011
comment
+1: Я забыл упомянуть конструкцию do {} while(0) в своем ответе. - person Oliver Charlesworth; 30.08.2011
comment
@Ron: На самом деле это позволяет вам писать: if(x) DO(m); else DO(n);. а решение @Oli выдаст ошибку компиляции. - person Nawaz; 30.08.2011
comment
Это одна из причин использовать встроенные функции, а не макросы! - person Bo Persson; 30.08.2011
comment
@Bo Persson: Какое решение вы предлагаете для использования встроенных функций? Пожалуйста, разместите. - person Nawaz; 30.08.2011
comment
DO (m) и DO (n) легко могут быть вызовами функций. Зачем заморачиваться с хитрыми макросами? - person Bo Persson; 30.08.2011
comment
Что ж, в этом случае MyObj необходимо передать в качестве аргумента этим функциям, так что это не капля замены. Более того, тогда вам придется возиться с параметрами указателя на член, что довольно быстро может стать некрасивым. Тем не менее, мне на самом деле не нравится использование макросов, чтобы скрыть происходящее, но вопрос был задан ... - person Roger Lipscombe; 31.08.2011
comment
а как насчет простого #define DO(WHAT) ; в ветке #else? - person Kristóf Szalay; 09.06.2017

Он кричит, потому что вы не можете этого сделать.

Я предлагаю в качестве альтернативы следующее:

#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT)
#endif
person Oliver Charlesworth    schedule 30.08.2011

Кажется, что то, что вы хотите сделать, можно достичь без каких-либо проблем:

#ifdef DEBUG
#    define DO(WHAT) MyObj->WHAT()
#else
#    define DO(WHAT) while(false)
#endif

Кстати, лучше использовать макрос NDEBUG, если у вас нет более конкретной причины не делать этого. NDEBUG более широко используется как макрос, что означает отсутствие отладки. Например, стандартный макрос assert можно отключить, указав NDEBUG. Ваш код станет:

#ifndef NDEBUG
#    define DO(WHAT) MyObj->WHAT()
#else
#    define DO(WHAT) while(false)
#endif
person Paul Manta    schedule 30.08.2011
comment
Вы должны подчеркнуть, что, поскольку NDEBUG означает отсутствие отладки, #ifdef становится #ifndef. - person ilpelle; 19.01.2018

Вы можете сделать то же самое вот так:

#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT)
#endif
person antlersoft    schedule 30.08.2011
comment
См. Другой способ избежать пустых операторов ... - person antlersoft; 30.08.2011

Как насчет:

#ifdef DEBUG
#define DO(WHAT) MyObj->WHAT()
#else
#define DO(WHAT)
#endif
person Miguel    schedule 30.08.2011