I'm wondering if I'm using variadic macros to create a function with default arguments, how should I add the prototype of this function to the interface header file So that I hide the base function from the user.
#define Enable_Asynchronous_Clock(...) Enable_Asynchronous_Clock_Base((struct Asynch_Args){.tcnt=0,.tccr=0,.ocr=0, __VA_ARGS__})
struct Asynch_Args{ u8 tcnt;u8 tccr;u8 ocr;};
void Enable_Asynchronous_Clock_Base(struct Asynch_Args argv){
//////
}
Is it even possible to add a prototype for this "Enable_Asynchronous_Clock(...)" or not.
At first, I thought of making it as a normal function with if/elifs that will at the end call the base function, But I came across this method and wanted to experiment with it a little.
You possibly might not want to allow passing arbitrary arguments to your function, so you might select default arguments depending on the number of arguments passed to, which might look as follows:
#define foo(...) CONCAT(foo_, ARG5(__VA_ARGS__, 5, 4, 3, 2, 1, 0))(__VA_ARGS__)
#define CONCAT(X, Y) CONCAT_(X, Y)
#define CONCAT_(X, Y) X ## Y
#define ARG5(_0, _1, _2, _3, _4, _5, ...) _5
void foo_5(int mandatory1, int mandatory2, int optional1, int optional2, int optional3)
{
}
#define foo_4(M1, M2, O1, O2) foo_5(M1, M2, O1, O2, 7)
#define foo_3(M1, M2, O1) foo_5(M1, M2, O1, 7, 7)
#define foo_2(M1, M2) foo_5(M1, M2, 7, 7, 7)
Demonstration see on godbolt.
You might event add overloaded variants for some of these foo_N
functions/macros – though I would not recommend to for types implicitly convertible one to another (like int
and double
) which might get too error prone (like having foo(7, 7, 7)
while foo(7, 7, 7.0)
was intended).
Admitted, the base functions/macros will remain visible to the user, but I do not really consider this much of an issue.