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)
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
I took Dabo's (https://stackoverflow.com/a/23238813/5126486) awesome solution and improved a little bit so it's easier to extend to more than 5:
#define UNUSED0()
#define UNUSED1(a) (void)(a)
#define UNUSED2(a,b) (void)(a),UNUSED1(b)
#define UNUSED3(a,b,c) (void)(a),UNUSED2(b,c)
#define UNUSED4(a,b,c,d) (void)(a),UNUSED3(b,c,d)
#define UNUSED5(a,b,c,d,e) (void)(a),UNUSED4(b,c,d,e)
#define VA_NUM_ARGS_IMPL(_0,_1,_2,_3,_4,_5, N,...) N
#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(100, ##__VA_ARGS__, 5, 4, 3, 2, 1, 0 )
#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__ )
You can use compile time __VA_ARGS__
macro.
#define UNUSED(...) (void)(__VA_ARGS__)
UPDATE: After lot of trials, I came up to an optimized solution:
#define UNUSED(...) __VA_ARGS__
int main()
{
int e, x;
char **a, **b, *c, d[45];
x = x, UNUSED(a, b, c, d, e), x;
return 0;
}
NOTES:
It doesn't eliminate warnings completely but reduces them to just 3
same type of warnings:
warning: value computed is not used
The first and last x
ensure assignment of same datatypes.
I will say it is optimized because for any number of unused variables it gives 3
warnings (I may be wrong, please test it yourself and do report me if you get more) and the amount of code (MACRO manipulations) required to achieve it is less.
I am still working on it, will post if I reach to any better solution.
What do you think about this:
#define UNUSED(...) [__VA_ARGS__](){};
Example:
void f(int a, char* b, long d)
{
UNUSED(a, b, d);
}
Should be expanded ad a lambdas definition:
[a,b,d](){}; //optimized by compiler (I hope!)
===== Tested with http://gcc.godbolt.org ===== I've tryed with this code:
#define UNUSED(...) [__VA_ARGS__](){};
int square(int num, float a) {
UNUSED(a);
return num * num;
}
The resulting output (compiled with -O0 -Wall) is:
square(int, float):
pushq %rbp
movq %rsp, %rbp
movl %edi, -4(%rbp)
movss %xmm0, -8(%rbp)
movl -4(%rbp), %eax
imull -4(%rbp), %eax
popq %rbp
ret
EDIT:
If you can use C++11 this could be a better solution :
template <typename ...Args>
void UNUSED(Args&& ...args)
{
(void)(sizeof...(args));
}