What if I told you that we can write functions in plain C that support named arguments, like for example in Scala or Python? Take a look at the following code:

int main() {
  int result;
  // No surprise here
  result = calculate_sum( 3, 4 );
  printf( "%d\n", result ); // prints 7

  // We can explicitly name arguments
  result = calculate_sum( .arg1 = 3, .arg2 = 4 );
  printf( "%d\n", result ); // prints 7

  // When we name arguments, we can also give them in
  // an arbitrary order
  result = calculate_sum( .arg2 = 4, .arg1 = 3 );
  printf( "%d\n", result ); // prints 7

  // Also, we can add optional named arguments
  result = calculate_sum( 3, 4, .subtract_one = true );
  printf( "%d\n", result ); // prints 6

  return 0;
}

The trick here is to create a structure that can hold the arguments of the call, and implement the function taking this structure instead of the single arguments. Then, using a combination of a #define with variable arguments that create a compound literal, we create the façade that is called as if it were the actual function:

struct _named_t {
  int arg1;
  int arg2;
  bool subtract_one;
};

int _calculate_sum(struct _named_t *args) {
  int result = args->arg1 + args->arg2;
  return args->subtract_one ? result - 1 : result;
}
#define calculate_sum(...) _calculate_sum(&(struct _named_t){ __VA_ARGS__ })

The struct will live on the caller’s stack in this implementation, but you could also just pass the whole struct into the function, as long as the struct doesn’t contain any arrays that you don’t want to copy every time the function is called.

You can find the whole file in this gist.


Please go here to comment this article.