c - Variadic UNUSED 函数/宏

标签 c macros c-preprocessor

抑制 C 编译器关于未使用变量的警告的众所周知且可移植的方法是(参见 unused parameter warnings in C code):

#define UNUSED(x) (void)(x)

我正在寻找一种方法来概括它以接受多个输入(不同类型):

void foo(int a, long b, void* c){

   /* Want this: */
   ALL_UNUSED(a, b, c);

   /* instead of: */
   UNUSED(a);
   UNUSED(b);
   UNUSED(c);
}

似乎可以解决问题的一种方法是使用可变参数函数

static inline void ALL_UNUSED(int dummy, ...) {}

但是,我怀疑这种解决方案在专家眼中是令人反感的。

是否有一种符合标准且可移植(即不使用 __attribute__((unused)))的方法来制作可变参数 UNUSED() 函数/宏?非常感谢!

编辑

在 C99 或 C 预处理器的上下文中,似乎没有一种干净的方法来完成我所要求的事情。这就是生活。

在他下面的回答中,@Dabo 展示了一种非常有趣的方法来完成我要求使用一系列宏的操作。这是简洁且信息丰富的(至少对我而言),所以我接受这个答案。也就是说,我不会将它部署在一个大项目中,因为它的眼泪足以超过它带来的好处(在我看来)。但人们在这里会得出不同的结论。

如下所述,使用空可变参数函数的方法也不完美。虽然它是一个非常优雅的单行代码,但它会引发有关未初始化变量的警告(如果是的话)。此外,您必须相信您的编译器会完全优化它,我原则上反对这一点,但我尝试过的所有编译器实际上都这样做了。

一个相关的案例是在早期的高级接口(interface)设计阶段之后对函数进行 stub 。然后你未使用的变量将全部是函数参数并按定义初始化,下面的方法可以正常工作

static inline void UNUSED(int dummy, ...) {}

void foo(int a, long b, void* c){
    UNUSED(a, b, b); /* No warnings */
}

最佳答案

基于这两个帖子 Variadic macro to count number of arguments , 和 Overloading macros我做了以下内容

#define UNUSED1(x) (void)(x)
#define UNUSED2(x,y) (void)(x),(void)(y)
#define UNUSED3(x,y,z) (void)(x),(void)(y),(void)(z)
#define UNUSED4(a,x,y,z) (void)(a),(void)(x),(void)(y),(void)(z)
#define UNUSED5(a,b,x,y,z) (void)(a),(void)(b),(void)(x),(void)(y),(void)(z)

#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5, N,...) N
#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1)

#define ALL_UNUSED_IMPL_(nargs) UNUSED ## nargs
#define ALL_UNUSED_IMPL(nargs) ALL_UNUSED_IMPL_(nargs)
#define ALL_UNUSED(...) ALL_UNUSED_IMPL( VA_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__ )

可以如下使用

 int main()
 {
    int a,b,c;
    long f,d;

    ALL_UNUSED(a,b,c,f,d);

    return 0;
  }

eclipse 宏扩展给出:

  (void)(a),(void)(b),(void)(c),(void)(f),(void)(d)

使用 gcc -Wall 编译,没有警告

编辑:

#define UNUSED1(z) (void)(z)
#define UNUSED2(y,z) UNUSED1(y),UNUSED1(z)
#define UNUSED3(x,y,z) UNUSED1(x),UNUSED2(y,z)
#define UNUSED4(b,x,y,z) UNUSED2(b,x),UNUSED2(y,z)
#define UNUSED5(a,b,x,y,z) UNUSED2(a,b),UNUSED3(x,y,z)

EDIT2

至于您发布的inline 方法,快速测试一下

int a=0;
long f,d;

ALL_UNUSEDINLINE(a,f,&d);

给出 'f' is used uninitialized in this function [-Wuninitialized] 警告。所以这里至少有一个用例打破了这种方法的普遍性

关于c - Variadic UNUSED 函数/宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23235910/

相关文章:

c - 使用 GDB 调试以编程方式调用的函数

c - 在 iMac 上使用 gcc 出现段错误

c - 异步编程

c++ - -D 选项从 g++ 命令行被错误地扩展

我可以在 C 预处理器中使用 ## 在循环中声明多个变量吗?

c - 编译 glibc 时 mipsel-gcc 产生的奇怪加载指令

c++ - 运行时如何在 Visual Studio C++ 中确定调试或 Release模式

c - 检测预处理器宏中的空参数

C++ 使用 __COUNTER__ 自动生成不同的命名函数

visual-studio - Visual Studio #if on Visual Studio 版本