无效声明的gcc警告.

Ale*_*dru 4 c gcc compiler-warnings

我有一个日志宏,它在发布模式下变为:

#define LOG (void)
Run Code Online (Sandbox Code Playgroud)

所以声明

LOG("foobar %d", 0xbabecafe);
Run Code Online (Sandbox Code Playgroud)

扩大到

(void)("foobar %d", 0xbabecafe);
Run Code Online (Sandbox Code Playgroud)

问题是最后一个表达式在gcc下产生一个警告:

warning: left-hand operand of comma expression has no effect [-Wunused-value]
Run Code Online (Sandbox Code Playgroud)

如何更改日志宏以便不发出警告?(注意,我不想添加编译标志-Wunused-value).

编辑我看到已经有几个答案涉及(...).在Minix下编译相同的文件,该文件不支持可变参数宏.最好的是拥有符合C89标准的解决方案.虽然你的答案是正确的(我赞成它),但我没有包含这个小细节是我的错.

Jan*_*dec 6

最简单的应该是

#define LOG(...) (void)0
Run Code Online (Sandbox Code Playgroud)

(gcc支持C99可变参数宏,而且大多数其他编译器也支持这些天)这将丢弃参数列表,它有两个优点:

  • 它不会创建没有效果的语句
  • 根本不评估参数(如果在参数列表中调用非内联函数,在您的版本中编译器无法消除它们,而使用可变参数宏,编译器根本不会看到它们.

  • @Alexandru:如果那个编译器没有给你警告,只需使用一些#ifdef magic来为gcc提供`LOG(...)`变体,使用minix编译器给`LOG`一个. (2认同)

Eva*_*ran 6

我认为旧学校处理这个问题的方法是利用双重优势.像这样的东西:

LOG(("message: %d", 10));
Run Code Online (Sandbox Code Playgroud)

然后对于您的宏,您可以像这样定义它:

#define LOG(x) printf x
Run Code Online (Sandbox Code Playgroud)

要么

#define LOG(x) (void)0
Run Code Online (Sandbox Code Playgroud)

由于双parens,预处理器将整个内部paren视为单个参数.这至少习惯于在visual studio中工作.

编辑:我做了一个快速测试,它使用gcc与-ansi,所以它应该是好的:

gcc -DNDEBUG -ansi -pedantic -W -Wall test.c -o test

#include <stdio.h>

#ifdef NDEBUG
#define LOG(x) printf x
#else
#define LOG(x) (void)0
#endif

int main() {
    LOG(("message: %d\n", 10));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)