Макрос отключить отпечатки printf

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

EDIT: Я лично использую gcc, но код является частью более крупного проекта, который будет скомпилирован на плате Panda с Ubuntu.

Ответ 1

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

#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, но я предполагаю, что вы также хотите избавиться от служебных программ.

Ответ 3

Два варианта:

#define printf(...)

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

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

int wrap_printf(void) {return 0;}

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

--wrap printf

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

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

Ответ 4

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

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

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

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

#include <stdio.h>

void main(void) {

        printf("normal print\n");

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

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

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

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

Ответ 5

Если вы хотите избежать потенциального предупреждения, которое может дать вам ответ Джонатана, и если вы не возражаете против пустого вызова 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*, ...)

Ответ 6

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

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

Ответ 7

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

Второй определяет, на основе первого макроса, вызов или нет 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

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

Ответ 8

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

Ответ 9

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

int printf(const char *fmt, ...)
{
return (0)
}