无效声明的gcc警告。

时间:2011-07-29 12:15:56

标签: c gcc compiler-warnings

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

#define LOG (void)

所以陈述

LOG("foobar %d", 0xbabecafe);

扩展为

(void)("foobar %d", 0xbabecafe);

问题是最后一个表达式在gcc:

下产生警告
warning: left-hand operand of comma expression has no effect [-Wunused-value]

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

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

5 个答案:

答案 0 :(得分:6)

最简单的应该是

#define LOG(...) (void)0

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

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

答案 1 :(得分:6)

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

LOG(("message: %d", 10));

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

#define LOG(x) printf x

#define LOG(x) (void)0

由于双重parens,预处理器将整个内部paren视为单个参数。这至少习惯于在视觉工作室工作。

编辑:我做了一个快速测试,它与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;
}

答案 2 :(得分:3)

#define LOG(...)似乎可以解决问题。

答案 3 :(得分:2)

对于不符合要求的C实现(甚至不是C89?)的问题,您可以执行类似

的操作
static void LOG(char *format, ...) { /* empty */ }

即使是完全愚蠢的编译器也应该能够优化它。

答案 4 :(得分:1)

我用过

#define LOG( t) t

用于开发版本和

#define LOG( t)

发布版本,典型用途为

LOG( printf( "here\n"));