Variadic UNUSED函数/宏

dag*_*dag 11 c macros c-preprocessor

抑制C编译器有关未使用变量的警告的一种众所周知的可移植方法是(参见C代码中未使用的参数警告):

#define UNUSED(x) (void)(x)
Run Code Online (Sandbox Code Playgroud)

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

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

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

   /* instead of: */
   UNUSED(a);
   UNUSED(b);
   UNUSED(c);
}
Run Code Online (Sandbox Code Playgroud)

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

static inline void ALL_UNUSED(int dummy, ...) {}
Run Code Online (Sandbox Code Playgroud)

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

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

编辑

在C99或C预处理器的上下文中似乎没有一种干净的方式来执行我的要求.这就是人生.

在下面的回答中,@ Dabo展示了一种非常有趣的方式来做我要求使用的一系列宏.这是整洁和翔实的(至少对我来说),所以我接受这个答案.也就是说,我不会将它部署在一个大型项目中,因为它的篇幅足以超过它带来的好处(在我看来).但人们会在这里得出不同的结论.

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

一个相关的情况是在早期高级接口设计阶段之后存根功能.那么你未使用的变量都将是函数参数并按定义初始化,以下方法可以正常工作

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

void foo(int a, long b, void* c){
    UNUSED(a, b, b); /* No warnings */
}
Run Code Online (Sandbox Code Playgroud)

Dab*_*abo 9

基于这两个帖子Variadic宏来计算参数的数量,并且重载宏我做了以下内容

#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__ )
Run Code Online (Sandbox Code Playgroud)

什么可以使用如下

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

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

    return 0;
  }
Run Code Online (Sandbox Code Playgroud)

eclipse宏扩展给出:

  (void)(a),(void)(b),(void)(c),(void)(f),(void)(d)
Run Code Online (Sandbox Code Playgroud)

编译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)
Run Code Online (Sandbox Code Playgroud)

EDIT2

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

int a=0;
long f,d;

ALL_UNUSEDINLINE(a,f,&d);
Run Code Online (Sandbox Code Playgroud)

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