Отключить функции с помощью MACROS - PullRequest
4 голосов
/ 10 октября 2011

После долгих поисков решения в Интернете я решил спросить здесь, подходит ли мое решение.

Я пытаюсь написать простую и модульную библиотеку журналов C, предназначенную для простого отключения и специально помогающую аспирантам и исследователям в отладке алгоритма, максимально снижающего влияние системы журналирования.

Моя проблема в том, что я хочу, чтобы пользователь библиотеки мог отключить систему журналирования во время компиляции, создавая исполняемый файл, в котором стоимость регистратора равна 0.

Код C будет выглядеть так:

...
logger_t * logger;

result = logger_init(logger);
if(result == -1) {...}
...

это просто инициализирует регистратор. В поисках примера кода я проверил заголовок assert.h, но это решение приводит к появлению списка предупреждений в моем случае. Фактически, если logger_init () заменить на 0 с использованием макроса, это приведет к тому, что регистратор переменных никогда не будет использоваться.

По этой причине я решил использовать этот подход:

int logger_init(logger_t *logger);

#ifndef NLOG /* NLOG not defined -> enable logging */
int logger_init(logger_t *logger) {
...
}
#else  /* NLOG defined --> the logging system must be disabled */
#define logger_init(logger)     (int)((logger = NULL) == NULL)
#endif /* NLOG */

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

int logger_init(logger_t *logger) {
  #ifndef NLOG /* NLOG not defined -> enable logging */
  ...
  #endif
  return 0;
}

продолжайте вызывать функцию, даже если она мне не нужна.

Как вы думаете, мое решение можно считать хорошим решением? Есть ли лучшее решение?

Большое спасибо, ребята! Ура, Armando

Ответы [ 2 ]

8 голосов
/ 10 октября 2011

Стандартная идиома для этого, по крайней мере в 90-х годах, была:

#ifndef NLOG
void logger_init(logger_t *logger);
void logger_log(logger_t *logger, ...);
#else
#define logger_init (void)sizeof
#define logger_log  (void)sizeof
#endif

Помните, что размер операндов не оценивается, хотя проверяется синтаксис. Этот прием также работает с переменными функциями, потому что оператор sizeof увидит выражение с несколькими операторами запятых:

logger_log(log, 1, 2, 3);

Преобразует в:

(void)sizeof(log, 1, 2, 3);

Эти запятые не разделяют параметры (sizeof не функция, а оператор), но они операторы запятой .

Обратите внимание, что я изменил возвращаемое значение с int на void. В этом нет особой необходимости, но возвращение sizeof будет в основном бессмысленным.

0 голосов
/ 10 октября 2011

Разве ваша отключенная версия не может быть просто константой:

#ifndef NLOG /* NLOG not defined -> enable logging */
int logger_init(logger_t *logger) {
...
}
#else  /* NLOG defined --> the logging system must be disabled */
#define logger_init(logger)     0
#endif /* NLOG */

Таким образом, у вас просто (после предварительной компиляции): result = 0;, которая не должна выдавать никаких предупреждений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...