Interfaces and traits in C

8 points by repl


pag

I recently implemented an approximation of interfaces/traits in C++20 using concepts and evil amounts of the pre-processor. It implements dynamic interfaces/traits in terms fat pointers, custom vtables rather than traditional C++ virtual methods backed by compiler-generated vtables, and a simplistic custom RTTI implementation. There are some different trade-offs, and less flexibility than Rust of course, but you can do things like: guarantee dynamic dispatch (using the fat pointer type), or generically handle either of dynamic or static (by using concept auto &&).

Overall I am quite happy with the experiment. It allows me to extend closed APIs as well as fundamental types. I can declare implementations in a variety of ways (methods, friend functions, plain old functions), and I have implemented a mechanism to sort-of-but-not-quite ensure const-correctness, where the vtable tracks if all methods can operate on const or non-const, and then casts from a type-erased fat pointer back to an implementation pointer type will check, based on the destination type qualification, whether or not const is required or not.

The implementation is mostly here and an example of a simple type-parameterized interface is here, and a more elaborate non-parameterized interface is here. The implementation of casting with const-checking is here.

lor_louis

I also make use of interfaces in C quite a bit, and I recently tried to compile one of my projects to WASM and learned (the hard way) that function casting is

  1. Undefined behaviour according to the C standard
  2. Straight up crashes on WASM because emscripten enforces strict type equality on function calls.

This means that something like.

int do_thing(int *i) { return *i };

auto f = (int*)(void *)do_thing;
int a = 0;
f(&a); // crashes on WASM

This made me change how I define interfaces, where I now always use void* for the self parameter.

Also, when using interfaces, LTO is pretty much required to get the compiler to inline as much as possible.