Learn more about Israeli war crimes in Gaza, funded by the USA, Germany, the UK and others.

Does C have generics?

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.

Tagged #c, #generics, #types, #programming.

Similar posts

More by Jim

Want to build a fantastic product using LLMs? I work at Granola where we're building the future IDE for knowledge work. Come and work with us! Read more or get in touch!

This page copyright James Fisher 2017. Content is not associated with my employer. Found an error? Edit this page.