C default arguments
Wow, everybody is such a pessimist around here. The answer is yes.
It ain't trivial: by the end, we'll have the core function, a supporting struct, a wrapper function, and a macroaround the wrapper function. In my work I have a set of macros to automate all this; onceyou understand the flow it'll be easy for you to do the same.
I've written this up elsewhere, so here's a detailed external link to supplement the summary here: http://modelingwithdata.org/arch/00000022.htm
We'd like to turn
double f(int i, double x)
into a function that takes defaults (i=8, x=3.14). Define a companion struct:
typedef struct { int i; double x;} f_args;
Rename your function f_base
, and define a wrapper function that sets defaults and callsthe base:
double var_f(f_args in){ int i_out = in.i ? in.i : 8; double x_out = in.x ? in.x : 3.14; return f_base(i_out, x_out);}
Now add a macro, using C's variadic macros. This way users don't have to know they'reactually populating a f_args
struct and think they're doing the usual:
#define f(...) var_f((f_args){__VA_ARGS__});
OK, now all of the following would work:
f(3, 8); //i=3, x=8f(.i=1, 2.3); //i=1, x=2.3f(2); //i=2, x=3.14f(.x=9.2); //i=8, x=9.2
Check the rules on how compound initializers set defaults for the exact rules.
One thing that won't work: f(0)
, because we can't distinguish between a missing value andzero. In my experience, this is something to watch out for, but can be taken care of asthe need arises---half the time your default really is zero.
I went through the trouble of writing this up because I think named arguments and defaults really do make coding in C easier and even more fun. AndC is awesome for being so simple and still having enough there to make all this possible.
Yes. :-) But not in a way you would expect.
int f1(int arg1, double arg2, char* name, char *opt);int f2(int arg1, double arg2, char* name){ return f1(arg1, arg2, name, "Some option");}
Unfortunately, C doesn't allow you to overload methods so you'd end up with two different functions. Still, by calling f2, you'd actually be calling f1 with a default value. This is a "Don't Repeat Yourself" solution, which helps you to avoid copying/pasting existing code.
Not really. The only way would be to write a varargs function and manually fill in default values for arguments which the caller doesn't pass.