可变参数未使用函数/宏 [英] Variadic UNUSED function/macro

查看:138
本文介绍了可变参数未使用函数/宏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个知名的便携方式燮约未使用的变量preSS C编译器的警告是(见的用C code 的未使用的参数警告):

 的#define未使用(X)(无效)(X)

我正在寻找一种方式来推广这个采取多种输入(不同类型):

 无效美孚(INT A,长B,无效* C){   / *想这一点:* /
   ALL_UNUSED(A,B,C);   /* 代替: */
   UNUSED(一);
   未使用(B);
   未使用(C);
}

这似乎这样的伎俩的方法之一是使用可变参数函数

 静态内嵌无效ALL_UNUSED(INT假人,...){}

不过,我怀疑这个解决方案是在专家的眼睛反感。

是否有一个标准的兼容性和移植(即不使用 __ __属性((未使用)))的方式,使一个可变参数未使用()函数/宏碁非常感谢!

修改

有似乎不存在做我要求在C99的上下文或的C preprocessor的清洁方式。生活就是这样。

在下面他的回答,@Dabo显示做我要求用一系列的宏的pretty有趣的方式。这是整洁和翔实的(至少对我来说),所以我接受的答案。这就是说,因为它是tearse足以超过它带来的利益(在我的眼前)我不会在一个大项目部署。但是,人们会得出不同的结论在这里。

如下所述,使用空可变参数函数的方法也不是完美的。虽然这是一个pretty优雅的一行代码,就会招来约unititialized变量警告(如果是)。此外,你必须信任你的编译器完全优化它了,这是我反对的原则,但我已经用实际做。

尝试了所有的编译器

一个相关的案例是早期的高级接口设计阶段后,存根函数时。然后,你的未使用的变量都将函数参数和定义初始化,以下办法正常工作

 静态内嵌无效使用(INT假人,...){}无效美孚(INT A,长B,无效* C){
    UNUSED(A,B,B); / *没有警告* /
}


解决方案

根据这两个职位的可变参数宏来计算参数的数目和的重载我做的宏以下

 的#define UNUSED1(X)(无效)(X)
的#define UNUSED2(X,Y)(无效)(x)时,(无效)(y)的
的#define UNUSED3(X,Y,Z)(无效)(x)时,(无效)(Y),(无效)(z)的
的#define UNUSED4(A,X,Y,Z)(无效)(一),(无效)(x)时,(无效)(Y),(无效)(z)的
的#define UNUSED5(A,B,X,Y,Z)(无效)(一),(无效)(b)中,(无效)(x)时,(无效)(Y),(无效)(z)的#定义VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,N,...)N
#定义VA_NUM_ARGS(...)VA_NUM_ARGS_IMPL(__ VA_ARGS__,5,4,3,2,1)#定义ALL_UNUSED_IMPL_(NARGS)未使用## NARGS
#定义ALL_UNUSED_IMPL(NARGS)ALL_UNUSED_IMPL_(NARGS)
#定义ALL_UNUSED(...)ALL_UNUSED_IMPL(VA_NUM_ARGS(__ __ VA_ARGS))(__ VA_ARGS__)

什么可以用作如下

  INT的main()
 {
    诠释A,B,C;
    长F,D;    ALL_UNUSED(A,B,C,F,D);    返回0;
  }

日食宏展开,得到:

 (无效)(一),(无效),(二),(无效),(三),(无效),(六),(无效)(D)

编译的gcc -Wall 没有警告

编辑:

 的#define UNUSED1(Z)(无效)(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

至于在线方法,你贴出来,快速测试

  int类型的= 0;
长F,D;ALL_UNUSEDINLINE(A,F,和D);

'F'都是在这个函数[-Wuninitialized] 警告使用未初始化。打破这种形式给出的一般性所以在这里至少有一个使用案例

A well-known and portable way to suppress C compiler warnings about unused variables is (see unused parameter warnings in C code):

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

I'm looking for a way to generalize this to take multiple inputs (of different type):

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

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

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

One way that seems to do the trick is to use a variadic function

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

However, I suspect this solution is objectionable in the expert eye.

Is there a standard-compliant and portable (i.e. not using __attribute__((unused))) way to make a variadic UNUSED() function/macro? Many thanks!

EDIT

There does not seem to exist a clean way of doing what I asked for in the context of C99 or the C preprocessor. Such is life.

In his answer below, @Dabo shows a pretty interesting way of doing what I asked for using a series of macros. This is neat and informative (at least to me), so I accept that answer. That said, I would not deploy it in a big project because it's tearse enough to outweigh the benefit it brings (in my eyes). But people will come to different conclusions here.

As noted below, the approach of using an empty variadic function is not perfect either. While it's a pretty elegant one-liner, it will provoke warnings about unititialized variables (if they are). Also, you have to trust your compiler to completely optimize it away, which I object to in principle but that all compilers I have tried with actually do.

One relevant case is when stubbing functions after an early high-level interface design phase. Then your unused variables will all be function arguments and initialized by definition, and the following approach works fine

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

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

解决方案

Based on these two posts Variadic macro to count number of arguments, and Overloading macros i made the following

#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__ )

what can be used as follows

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

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

    return 0;
  }

eclipse macro expansion gives :

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

compiled with gcc -Wall with no warnings

EDIT:

#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

As for inline method you posted, a quick test

int a=0;
long f,d;

ALL_UNUSEDINLINE(a,f,&d);

gives ‘f’ is used uninitialized in this function [-Wuninitialized] warning. So here at least one use case which breaks generality of this aproach

这篇关于可变参数未使用函数/宏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆