功能宏,其计算结果为零,可用作语句

时间:2012-04-17 11:52:37

标签: c c-preprocessor

我们有一个带#define FOO(arg) foo(arg)的函数宏int foo(const char* bar);。当定义NDEBUG时,FOO定义为#define FOO(arg) 0,但这会导致许多编译器警告,因为在许多情况下不使用FOO的返回值。该解决方案应与ANSI C编译器一起使用,并且不会发出警告。我试过了:

(void)0:不能被赋予变量

static int foo(const char* bar) { return 0; }:在某些模块中导致未使用的静态功能警告

static inline int foo(const char* bar) { return 0; }:仅适用于C99编译器

感谢您的帮助!

EDIT1: 它有点像跟踪宏,并在整个项目中使用。它主要用作FOO("function x called");之类的语句,但在少数情况下我看到if (FOO("condition a")) { /* some more debug output */ }。在NDEBUG定义和优化的情况下,FOO不应该留下任何东西。我没有提出这个,但我必须清理这个烂摊子:)。

edit2:我应该补充一点,对于gcc发布版本,使用了这些标志:-O3 -Wall -ansi

edit3:现在我要去__inline int dummy() { return 0; }。 __inline在ansi模式下与VisualC和GCC一起使用。

3 个答案:

答案 0 :(得分:3)

猜测它有点依赖于编译器,但这应该有效:

#ifndef NDEBUG
    #define FOO(arg) foo(arg)
#else
    #define FOO(arg) ((int)0)
#endif

它可以防止"表达无效"警告,它什么都不做,使用时它的值仍为0.

<强> EDITED
它看起来不那么便携,所以(现在)你有这些条件:

  • (0)((int)0)至少在VC 2010上工作。
  • __noop应该适用于2003年以后的任何版本的VC。

VC6不是问题,因为它根本不会发出C4555警告。对于其他编译器,您可以使用:

  • ((void)0, 0)它可能适用于很多编译器(可能它是更便携的编译器吗?)。
  • inline int foo(const char* bar) { return 0; }适用于任何其他C99编译器(如您所写,您可能需要在gcc上将其声明为static。)

对于任何其他史前C编译器,请使用@Jobs指出的解决方案:abs(0)

答案 1 :(得分:2)

可以做什么来防止警告如下:

#ifndef NDEBUG
    #define FOO(arg) foo(arg)
#else
    #define FOO(arg) abs(0)
#endif

我并不是说这是理想的(例如,你必须确保stdlib.h包含在所有地方)但它确实会阻止警告。

答案 2 :(得分:1)

我会做一些依赖于C版本的东西。在头文件中:

#if __STDC_VERSION__ > 199900L
inline int foo(const char* bar) { return 0; }
#else
int foo(const char* bar);
#endif

在一个编译单元中

#if __STDC_VERSION__ < 199900L
int foo(const char* bar) { return 0; }
#else
int foo(const char* bar);
#endif

或者用于旧的C版本,比如Job的答案,这是一个肯定会被优化但不会产生警告的函数。