What is the universal way of resolving
warning: ISO C++11 requires at least one argument for the "..." in a variadic macro
warning introduced by -pedantic
flag for gcc?
Consider following example
#define FUNCTION_DECL(ret, name, ...) ret name(__VA_ARGS__)
FUNCTION_DECL(int, foo, int bar, int quax)
{
return bar + quax;
}
FUNCTION_DECL(void, no_args)
{
}
Expansion of no_args
macro produces error above.
Example of solution to that would be to have two macros and then simple overload trick
#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, NAME, ...) NAME
#define METHOD_DECL2(ret, name) ret name()
#define METHOD_DECL3(ret, name, ...) ret name(__VA_ARGS__)
#define METHOD_DECL(...) GET_MACRO(__VA_ARGS__, METHOD_DECL3, METHOD_DECL3, METHOD_DECL3, METHOD_DECL3, METHOD_DECL3, METHOD_DECL3, METHOD_DECL3, METHOD_DECL2)(__VA_ARGS__)
Then METHOD_DECL(void, no_args)
no longer triggers an error.
Sadly, it doesn't work in MSVC2017, but is fixed in latest preview of MSVC2019.
And this solution is somewhat clumsy. I tried to think about different solution, something like
#define EXTRACT_FIRST(_1, ...) _1
#define OMIT_FIRST(_1, ...) __VA_ARGS__
#define METHOD_DECL(ret, ...) ret EXTRACT_FIRST(__VA_ARGS__) OMIT_FIRST(__VA_ARGS__)
But this just moved the problem, since now OMIT_FIRST
triggers this error
EDIT:
What I am trying to do is following:
I have function in AVR assembler (micro-controler)
delay_37us:
ldi r16, 227
delay_592c_aw:
dec r16
brne delay_592c_aw
nop
nop
ret
That active waits for 592cycles (which is 37us for 16MHz cpu)
In order to call this function in C, I have to mark it as .global
and also provide C declaration of such function. In order to simplify declaration of such function I would use a macro like that
FUNCTION_DECL(void, delay_37us);
which would be defined as
#ifdef __ASSEMBLER__
#define FUNCTION_DECL(ret, name, ...) .global name
#else
#define FUNCTION_DECL(ret, name, ...) ret name(__VA_ARGS__)
#endif
So that I could use one header file for both C and ASM. What I am using currently is one header file with following content
#ifdef __ASSEMBLER__
.global delay_37us
.global delay_ms
.global delay_1s
#else
void delay_37us();
void delay_ms(unsigned char);
void delay_1s();
#endif
Which is error-prone to maintain.