Generics in C?

Take the following C program:

#include <stdio.h>
int main() {
  char* x = "foo";
  printf("Type of x is: %s\n", _Generic(x, char*: "string", int: "int"));
  return 0;
}

It produces:

$ clang generic.c
$ ./a.out
Type of x is: string

The new expression in this program is _Generic(x, char*: "string", int: "int"), which we see evaluates to "string". The _Generic(...) expression form is new in C11. It is evaluated at compile-time based on the type of its first argument, in this case x of type char*. The following char*: "string", int: "int" is an association list, mapping types to expressions. The compiler selects the expression associated with the type of the first argument; thus in this case it selects "string" and the program is transformed at compile-time to:

  printf("Type of x is: %s\n", "string");

The _Generic(...) expression can be used for overloaded functions. For example, a max function which selects a concrete implementation depending on the type of the arguments:

#include <stdio.h>
#include <string.h>

int max_int(int a, int b) { return (a < b ? b : a); }
char* max_string(char* a, char* b) { return (strcmp(a, b) < 0 ? b : a); }

#define max(X, Y) ((_Generic((X), int: max_int, char*: max_string))(X,Y))

int main() {
  int ix = 5; int iy = 6;
  printf("Max of %d and %d is: %d\n", ix, iy, max(ix, iy));

  char* sx = "foo"; char* sy = "bar";
  printf("Max of %s and %s is: %s\n", sx, sy, max(sx, sy));

  return 0;
}

Despite the name, this is not generics! A true “generics in C” feature would allow you to define:

T max<T>(T a, T b) { return (a < b ? b : a); }

In _Generic, all concrete implementations must be manually written, rather than generated through type-instantiation. More importantly, in _Generic, the set of max functions is closed; to add a new max function for a new type, one must have access to the definition of max. In a true generics feature, max can be generated for any user type with < defined on it.


I wrote this because I felt like it. This post is my own, and not associated with my employer.

Jim. Public speaking. Friends. Vidrio.