我有点不太愿意发布这个答案,因为它使用的宏技巧可能会成为问题的根源。然而 -
如果你想要消除的函数调用总是单独在语句中使用(即,它们从未是更大表达式的一部分),那么类似以下的代码可能有效(并且它可以处理可变参数):
所以,如果你有这行代码:
foo( "this is a %s - a++ is %d\n", "test", a++);
在预处理步骤之后,它将最终变成以下之一:
MyFunction( "this is a %s - a++ is %d\n", "test", a++);
或者
(1) ? ((void) 0) : (void)( "this is a %s - a++ is %d\n", "test", a++);
这将伪函数的参数列表转换为一堆由逗号运算符分隔的表达式,这些表达式永远不会被评估,因为条件始终返回((void) 0)
结果。
这个变体与ChriSW和Jonathan Leffler建议的东西非常接近:
这与要求编译器支持可变参宏(__VA_ARGS__
)的方法略有不同。
我认为这可以用于消除调试跟踪函数调用,这些函数调用通常从未组合成更大的表达式,但除此之外,我认为这是一种危险的技术。
请注意潜在的问题 - 特别是如果调用中的参数产生副作用(这是宏的常见问题 - 不仅仅是这个hack)。在这个示例中,只有在构建中定义了SOMETHING
时,a++
才会被计算。因此,如果调用后的代码依赖于增加的a
的值,则其中一个构建存在错误。