Hacker News new | ask | show | jobs
by cyanic 2041 days 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.
2 comments

In 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.
If other people use and debug your code please consider NOT using “#define” meta programming. They are a nightmare to debug.
This!

I just wanted to post it, but you already did. :-)