2010-11-04 2 views
18

У меня есть набор отладочных макросов в tracing.hh. Будь то генерирует код и выход управляется макро флагом в режиме реального исходного кода:Тест для определения пустого макроса

// File: foo.cc 
#define TRACING 0 
#include "tracing.hh" 
// Away we go . . . 
TRACEF("debug message"); 

трассировку флаг должен иметь значение; Я обычно переключаться между 0 и 1.

В tracing.h,

  • #ifdef TRACING скажет мне, что трассировка была определена.
  • #if TRACING управляет определение функциональных макросов, как TRACEF()

Но что, если трассировка не имеет значения? Затем #if TRACING выдает ошибку:

In file included from foo.c:3: 
tracing.hh:73:12: error: #if with no expression 

Как я могу проверить, если трассировка определено, но не имеет никакого значения?

ответ

0

бы

#if defined(TRACING) && !TRACING 

сделать трюк?

+0

Почти, я думаю. См. Следующий ответ: – pdbj

+4

Это, к сожалению, не сработает. Вы столкнетесь с той же проблемой, когда TRACING будет удален. У вас будет что-то вроде: «#if defined (TRACING) &&!». Таким образом, «error: operator»! не имеет права операнд "будет расти во время сборки. – ForceMagic

22

С предложением Матти и еще несколько выступов я думаю, что проблема заключается в следующем: если TRACING не имеет значения, нам нужно иметь действующее выражение препроцессора в тесте #if .... Gnu cpp manual говорит, что он должен оценивать целочисленное выражение, поэтому нам нужно выражение, которое действительно, даже если один из аргументов отсутствует. То, что я, наконец, попал на это:

#if (TRACING + 0) 
# . . . 
  • Если TRACING имеет числовое значение (как в #define TRACING 2 \n), касты имеют действительное выражение, и мы не изменили значение
  • Если TRACING не имеет никакого значения. (как в #define TRACING \n), препроцессор оценивает #if (+0) к false

единственный случай, это не ручка

  • Если TRACING имеет токен (, то есть, ON). В руководстве cpp говорится: «Идентификаторы, которые не являются макросами ... считаются числом ноль,», которое оценивается как false. В этом случае, однако, было бы разумнее рассмотреть это значение true. Единственными жетонами, которые делают правильные вещи, являются булевы литералы true и false.
+0

Вы все еще можете выполнить тест времени выполнения, выполнив макрокоманду с помощью оператора '#'. C++ 11 может превратить это в тест времени компиляции (я полагаю, что использование 'constexpr' может быть способом), но не препроцессорным. –

+0

также у вас нет средств для разграничения между пустым и 'TRACING' равно 0 –

+0

' # if' определяет 0, если не найден. это не работает –

1

Late к партии, но я нашел хороший трюк, чтобы отличить -DTRACING=0 от -DTRACING:

#if (0-TRACING-1)==1 && (TRACING+0)!=-2 
#error "tracing empty" 
#endif 

Если TRACING пусто, то выражение для 0--1 =>1.

Если TRACING равен 0, то выражение для 0-0-1 =>-1

Я добавил дополнительную проверку в случае TRACING==-2 который сделал бы первый тестовый проход.

Это не работает для строковых литералов, конечно.

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