3 ms·
Named parameters using a struct. struct calculate_args { int x, y; enum {add=0, sub} operator; }; int calculate_func(struct calcul
by cyanic 6y ago
Named parameters using a struct.
struct calculate_args {
int x, y;
enum {add=0, sub} operator;
};
int calculate_func(struct calculate_args args) {
if (args.operator == add)
return args.x + args.y;
else
return args.x - args.y;
}
#define calculate(...) calculate_func((struct calculate_args){__VA_ARGS__})
Now you can combine positional and named parameters or omit them.
calculate(1, 3); // 4
calculate(8, 3, .operator=sub); // 5
calculate(.operator=sub, .y=7); // -7
Works very well in cases where there is a lot of parameters that default to 0.
Keep in mind that you still need to know how structs work and you lose compile-time error detection.
- beeforpork 6y agoThis! I just wanted to post it, but you already did. :-)
- johndough 6y agoIn a similar spirit, overloading functions based on the number of parameters. Even works with tcc. #include <stdio.h> #define CONCAT2(a, b) a##b #define CONCAT(a, b) CONCAT2(a, b) #define COUNT_ARGS2(a0, a1, a2, a3, a4, a5, a6, a7, a8, N, ...) N #define COUNT_ARGS(...) COUNT_ARGS2(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1) #define foo(...) CONCAT(foo_, COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__) void foo_1(const char *a){ printf("one arg: %s\n", a); } void foo_2(int a, int b){ printf("two args: %i and %i\n", a, b); } int main(){ foo("asdf"); foo(314159, 271828); } Small gotcha: Does not work with zero parameters, but functions with zero parameters probably mess with global state and that's evil anyway.
- noncoml 6y agoIf other people use and debug your code please consider NOT using “#define” meta programming. They are a nightmare to debug.