我想创建一个宏,将所有对printf
,更具体地说mbedtls_printf
(与printf
的行为完全相同)的调用全部替换为空。
我知道我可以使用#define mbedtls_printf
来代替mbedtls_printf
,但是仍然可以保留参数/括号。
编辑-我忘了提到mbedtls_printf
是一个用sgx_printf
取代自己的宏
答案 0 :(得分:3)
我会选择:
#define printf(...) (0)
这样做的好处是,如果有人真的不愿意检查一下printf的返回值(很少但并非闻所未闻),它将继续编译。
答案 1 :(得分:2)
以下工作,至少在gcc 8上有效。简短搜索表明,可变参数宏是C99引入的。
#define printf(...) do { } while (0)
int main()
{
printf("Hello %s?\n", "world");
return 0;
}
您想使用“在(0)时做{}时做”的技巧,以避免出现类似的意外情况:
if (something)
printf("Something else");
will_this_be_invoked_or_not();
您无法使printf()
完全消失。因为这会使下一行成为前面if
语句的逻辑部分。随之而来的是种族歧视。这就是为什么您仍然必须保留一些内容的原因。
答案 2 :(得分:2)
如果您完全不使用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()
。
答案 3 :(得分:1)
我知道我可以使用#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(逗号运算符返回其右手操作数)。这样的表达式已悄然优化。
答案 4 :(得分:1)
只需使用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)