Default values on arguments in C functions and function overloading in C
No, Standard C does not support either. Why do you feel you need to convert your C++ code to C? That could get quite tricky - I'd have thought writing wrappers would be the way to go, if your C++ must be callable from C.
Nevertheless I found a "trick" to do so if you use GCC (edit December 2020) or any compiler compatible with C++2a -yes it works with 'plain C' since it is a pre-compiler trick-.
GCC has a handy ## extension on variadic macro that allows you to simulate a default argument.
The trick has limitations: it works only for 1 default value, and the argument must be the last of you function parameters.
Here is a working example.
#include <stdio.h>
#define SUM(a,...) sum( a, (5, ##__VA_ARGS__) )
int sum (a, b)
int a;
int b;
{
return a + b;
}
main()
{
printf("%d\n", SUM( 3, 7 ) );
printf("%d\n", SUM( 3 ) );
}
In this case, I define SUM as a call to sum with the default second argument being 5.
If you call with 2 arguments (first call in main), it would be prepocessed as: sum( 3, (5, 7) );
This means:
- 1st argument is 3
- second argument is the result of the sequence (5, 7)... which is obviously 7!
As gcc is clever, this has no effect on runtime as the first member of the sequence is a constant and it is not needed, it will simply be discarded at compile time.
If you call with only one argument, the gcc extension will remove the VA_ARGS AND the leading coma. So it is preprocessed as:
sum( 3, (5 ) );
Thus the program gives the expected output:
10
8
So, this does perfectly simulate (with the usual macro limitations) a function with 2 arguments, the last one being optional with a default value applied if not provided.
Edit
-a) It does also work with CLANG (and possibly other compilers)
-b) A version that does NOT complain about unused arguments:
#define DEF_OR_ARG(z,a,arg,...) arg
#define SUM(a,...) sum( a, DEF_OR_ARG(,##__VA_ARGS__,__VA_ARGS__,5))
[Edit - October 2020] :
You could also try the new __VA_OPT__
that was standardised with c++2a (and should work in plain C too) instead of ## which is a gcc extension. Typical usage is __VA_OPT__(,)
that would add the coma when the argument list is non-empty and otherwise outputs nothing.
[Edit - December 2020] :
So the above trick, with __VA_OPT__
, becomes:
#define DEF_OR_ARG(value,...) value
#define SUM(a,...) sum( a, DEF_OR_ARG(__VA_ARGS__ __VA_OPT__(,) 5))
Unlike the 'sequence trick' that might complain for unused variables, this only involves the pre-compiler and is more readable.
When SUM is called with only one argument, ...
is empty and __VA_OPT__
does not output anything, thus DEF_OR_ARG(__VA_ARGS__ __VA_OPT(,) 5)
becomes DEF_OR_ARG( 5)
When SUM is called with a second argument, ...
is this second argument and __VA_OPT__
expands to the value given which is a coma. In that case
DEF_OR_ARG(__VA_ARGS__ __VA_OPT(,) 5)
becomes DEF_OR_ARG(second_argument_of_SUM , 5)
Now the expansion of DEF_OR_ARG
happens. This one is easy since it considers only the first argument and just discards the rest.
So, when SUM
was called with no second argument (first case above), the first argument to DEF_OR_ARG
is our default value. In the case there was a second argument to SUM
, it becomes the first argument to DEF_OR_ARG
that will expand to that and discard the default which is now second argument.