Макрос для отключения операторов printf - PullRequest
20 голосов
/ 23 апреля 2011

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

РЕДАКТИРОВАТЬ: Я лично использую gcc, но код является частью более крупного проекта, который будет скомпилирован на плате Panda под управлением Ubuntu.

Ответы [ 9 ]

22 голосов
/ 23 апреля 2011

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

#if 1
  #define SPAM(a) printf a
#else
  #define SPAM(a) (void)0
#endif

Так что я могу сделать это по всему коду

SPAM(("foo: %d\n", 42));

, а затем отключите их все, изменив 1 на 0 в #if выше.

Но если у вас есть поддержка макроса с переменным числом аргументов во всех компиляторах, которые вы пишете кодибо, тогда вы можете перейти к другим ответам и просто переопределить printf.(При этом я считаю полезным отличать отладочные отпечатки от обычных в коде - использование другого имени функции помогает удобочитаемости.)

Обратите внимание, что вы также можете перенаправить stdout на /dev/null, ноЯ предполагаю, что вы также хотите избавиться от накладных расходов во время выполнения.

15 голосов
/ 23 апреля 2011
#ifdef IGNORE_PRINTF
#define printf(fmt, ...) (0)
#endif

См. Также C #define макрос для отладочной печати , в котором обсуждаются некоторые важные вопросы, тесно связанные с этим.

9 голосов
/ 23 апреля 2011

Два варианта, либо:

#define printf(...)

(требуются переменные макропараметры C99), вам нужно поместить его в какой-нибудь общий заголовочный файл, который никогда не включается в stdio.h, если он есть.

Или вы можете указать компоновщику связать его с чем-то другим, в GCC вы бы определили

int wrap_printf(void) {return 0;}

и ссылку, используя

--wrap printf

Все, что сказал, вывероятно, следует использовать не printf для печати отладочных выводов, а скорее макрос или служебную функцию (которая, в свою очередь, может использовать printf, если хотите), которую вы лучше контролируете.

Надеюсь, это поможет.

3 голосов
/ 22 февраля 2013

Я использую префикс отладочных printf () (не всех) с PDEB.

Для отладочных сборок я компилирую с -DPDEB = (ничего)

Для сборок выпуска я компилирую с -DPDEB = "0 &&" или -DPDEB = "0 &&"

Таким образом, следующий код (test.c):

#include <stdio.h>

void main(void) {

        printf("normal print\n");

        PDEB printf("debug print\n");
}

выходы: либо (в режиме релиза): обычная печать

либо (в режиме отладки): нормальная печать отладочная печать

В идеале можно попытаться превратить PDEB в «//» (отметка комментариев), за исключением того, что это невозможно в рамках стандартной цепочки предварительной обработки / обработки.

1 голос
/ 24 апреля 2011

Если вы хотите избежать потенциального предупреждения, которое может дать вам ответ Джонатана, и если вы не возражаете против пустого вызова printf, вы также можете сделать что-то вроде

#define printf(...) printf("")

Это работает, потому что Cмакросы не являются рекурсивными.Расширенная printf("") будет просто оставлена ​​как таковая.

Другой вариант (поскольку вы используете gcc) будет выглядеть примерно так:

inline int ignore_printf(char const*, ...) 
         __attribute__ ((format (printf, 1, 2)));
inline int ignore_printf(char const*, ...) { return 0; }

#define printf ignore_printf

и в одном модуле компиляции

int ignore_printf(char const*, ...)
0 голосов
/ 21 ноября 2016

Ниже простая функция служит цели, я использую то же самое.

int printf(const char *fmt, ...)
{
return (0)
}
0 голосов
/ 26 февраля 2015

Я включил #define printf // в общий заголовочный файл. Это будет подавлять все printf.

0 голосов
/ 24 апреля 2011

Я использовал два макроса для этого. Первый определяет условие для печати. В этом простом примере мы печатаем каждый раз, когда параметр не равен нулю. Можно использовать более сложные выражения.

Второй определяет, на основании первого макроса, вызывать или нет printf.

Если условие может быть определено компилятором (с правильными настройками оптимизации), код не генерируется.

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

#define need_to_print(flag) ((flag) != 0))

#define my_printf(debug_level, ...) \
  ({ \
    if(need_to_print(debug_level)) \
      printf(__VA_ARGS__); \
  })

чтобы использовать его, вызовите my_printf вместо printf и добавьте параметр в начале для условия печати. ​​

my_printf(0, "value = %d\n", vv);  //this will not print
my_printf(1, "value = %d\n", vv);  //this will print

my_printf(print_debug, "value = %d\n", vv);  //this will print if print_debug != 0

круглые скобки (...), окружающие макрос, делают его единственным выражением.

0 голосов
/ 23 апреля 2011

Другая возможность будет что-то вроде freopen("/dev/null", "w", stdout);

Это не совсем отключает printf, хотя - это примерно эквивалентно запуску вашей программы с перенаправлением stdout в / dev / null, например: ./myprog > /dev/null в приглашении оболочки.

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