Тест для определения пустого макроса - PullRequest
21 голосов
/ 05 ноября 2010

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

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

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

Внутри tracing.h,

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

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

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

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

Ответы [ 3 ]

25 голосов
/ 08 ноября 2010

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

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

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

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

Поздно на вечеринку, но я нашел хороший трюк, чтобы отличить

#define TRACING 0

от

#define 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, которая сделает первый тестовый проход.

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

0 голосов
/ 05 ноября 2010

Может ли

#if defined(TRACING) && !TRACING

добиться цели?

...