Макрос, который заменяет все вызовы printf ничем - PullRequest
0 голосов
/ 23 ноября 2018

Я хочу создать макрос, который заменяет все вызовы на printf, а точнее mbedtls_printf (который ведет себя точно так же, как printf), на ничто.

Я знаю, что могу использовать #define mbedtls_printf заменить mbedtls_printf ничем, но это все равно оставит параметры / круглые скобки без изменений.

Редактировать - я забыл упомянуть, что mbedtls_printf - это макрос, который заменяет себя sgx_printf

Ответы [ 5 ]

0 голосов
/ 23 ноября 2018

Если вы полностью не отключите операторы printf, может быть скрыта ошибка.Рассмотрим следующий код:

printf("Result is %d\n", DoSomethingVeryImportant());

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

И я полагаю, что вы, возможно, захотите, чтобы ваш mbedtls_printf фактически вызывал printf для отладочных сборок, но не включался в розничную сборку.

Если все вышеперечисленное имеет значение, рассмотрите это как mbedtls_printf.h:

#ifndef MBEDTLS_PRINTF_H
#define MBEDTLS_PRINTF_H

#include <stdarg.h>
#include <stdio.h>

#ifdef DEBUG_BUILD
inline int printf_stub(const char* s, ...)
{
    va_list args;
    va_start(args, s);
    vprintf(s, args);
    va_end(args);
}

#define mbedtls_printf(...) printf_stub(__VA_ARGS__)

#else
inline int printf_stub(...){return 1;}
#define mbedtls_printf(...) printf_stub(__VA_ARGS__)
#endif

#endif

Затем в коде:

#include <iostream>
#include "mbedtls_printf.h"

int ImportantFunction()
{
   std::cout << "Really important code" << std::endl;
   return 42;
}

int main()
{
    mbedtls_printf("Result of a very important step: %d\n", ImportantFunction());
    mbedtls_printf("This just happened");
    mbedtls_printf("Result of a another important step: ", 43, 44, ImportantFunction());
    return 0;
}

Компилятор оптимизирует пустой вызов функции ипо-прежнему вызывать ImportantFunction(), как это было первоначально.

0 голосов
/ 23 ноября 2018

Я хотел бы пойти с:

#define printf(...) (0)

Преимущество здесь в том, что он будет продолжать компилироваться в тех случаях, когда кто-то действительно не хочет проверять возврат из printf (редко, но не случайно).

0 голосов
/ 23 ноября 2018

Следующие работы, по крайней мере, с gcc 8. Краткий поиск показывает, что с C99 были введены переменные макросы:

#define printf(...) do { } while (0)

int main()
{
    printf("Hello %s?\n", "world");
    return 0;
}

Вы хотите использовать ol '"do {} while (0)"уловка, чтобы избежать неожиданностей как:

if (something)
    printf("Something else");

will_this_be_invoked_or_not();

Вы не можете заставить printf() исчезнуть полностью.Потому что это сделает следующую строку логической частью предыдущего оператора if.Хилларность наступает.Вот почему вы все равно должны что-то оставить на месте.

0 голосов
/ 23 ноября 2018

Просто используйте лямбда : ( Variadic macro начиная с C99 )

#define printf(...) []{}()

Что это делаетпросто замените вызовы printf() на []{}() ... Это просто означает пустой вызов функции ... который можно отформатировать так:

#define printf(...) [] { \
                       }()

Или даже этодостаточно:

// Replacing printf() with an empty function that just takes variadic arguments
#define printf [](...){}

Редактировать: Вы можете также использовать:

#define printf void(0)
0 голосов
/ 23 ноября 2018

Я знаю, что могу использовать #define mbedtls_printf, чтобы заменить mbedtls_printf ничем, но при этом параметры / скобки останутся нетронутыми.

Это нормально, если список аргументов остается, потому что тогдаэто будет рассматриваться как выражение.Если у нас есть выражение и мы ничего не делаем с ним, то оно будет просто оптимизировано (на любом приличном компиляторе).Рассмотрим следующее :

int x(char a, double b)
{
    return printf("%c %f\n", a, b);
}

#define x 

int main(void)
{
    x('P', 3.14);
}

Компилятор видит следующий код для main:

('P', 3.14);

Это выражение оценивается как 3.14 (оператор запятой возвращает егоправый операнд).Такое выражение тихо оптимизировано.

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