繁体   English   中英

函数宏,其值为零,可以用作语句

[英]Function macro that evaluates to zero and can be used as a statement

我们有一个函数宏#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 int foo(const char* bar) { return 0; } :导致某些模块未使用的静态函数的警告

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

谢谢你的帮助!

edit1:它有点像跟踪宏,并在整个项目中使用。 通常,它只是用作FOO("function x called");类的语句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 int dummy() { return 0; } __inline在ansi模式下与VisualC和GCC一起使用。

这有点依赖编译器,但这应该可以工作:

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

它防止“表达式无效”警告,它不执行任何操作,使用时其值仍为0。

已编辑
似乎它不是那么可移植的,因此(现在)您具有以下条件:

  • (0)((int)0)至少在VC 2010上有效。
  • __noop在2003年之后的任何版本的VC上都可以使用。

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

  • ((void)0, 0)它可以在许多编译器上运行(也许是更可移植的编译器?)。
  • inline int foo(const char* bar) { return 0; } inline int foo(const char* bar) { return 0; }可与任何其他C99编译器一起使用(如您所写,您可能需要在gcc上将其声明为static )。

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

可以采取以下措施来防止该警告:

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

我并不是说这很理想(例如,您必须确保在所有位置都包含stdlib.h ),但是它确实可以防止警告。

我会做一些依赖于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的答案之类的功能,该功能肯定已经过优化,但不会产生警告。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM