代码之家  ›  专栏  ›  技术社区  ›  Foobar

宏,该宏将所有对printf的调用都替换为零

  •  5
  • Foobar  · 技术社区  · 6 年前

    我想创建一个宏来替换对的所有调用 printf ,更具体地说 mbedtls_printf printf

    我知道我可以用 #define mbedtls_printf 取代 不带任何内容,但这仍然会保留参数/括号不变。

    mbedtls_printf 是将自身替换为的宏 sgx_printf

    5 回复  |  直到 6 年前
        1
  •  1
  •   lost_in_the_source    6 年前

    我知道我可以使用#define mbedtls_printf将mbedtls_printf替换为空,但这仍然会保留参数/括号不变。

    如果参数列表保持不变,这没关系,因为它将被视为一个表达式。如果我们有一个表达式,而我们对它不做任何修改,那么它将被优化掉(在任何合适的编译器上)。考虑 the following :

    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(逗号运算符返回其右操作数)。这样一个表达式被悄悄地优化了。

        2
  •  3
  •   SoronelHaetir    6 年前

    #define printf(...) (0)
    

    这里的好处是,如果有人真的费心检查printf的返回,它将继续编译(很少,但并非闻所未闻)。

        3
  •  2
  •   Hong Ooi    6 年前

    以下工作,至少在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 陈述接着是山丘。这就是为什么你仍然需要保留一些东西。

        4
  •  2
  •   selbie    6 年前

    如果完全没有输出printf语句,则可能存在一个潜在的bug。考虑下面的代码:

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

    当您用宏替换printf调用时,您可能仍然希望确保内部函数调用 DoSomethingVeryImportant() 被调用。否则,您已经更改了程序的逻辑。

    #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()

        5
  •  1
  •   Ruks    6 年前

    只需使用 lambda : ( Variadic macros 自从 C99 )

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

    这样做只是简单地替换 printf() 呼叫 []{}() ... 这只意味着一个空函数调用。。。其格式可以如下所示:

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

    或者,这就足够了:

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

    编辑: 可以 也可使用:

    #define printf void(0)