

To add something to this: linux has avoided internal SPIs for a long time. It’s often lauded as one of the reasons it hasn’t ossified.
However, some subsystems have a huge amount of complexity and hidden constraint in how you correctly use them. Some of that may be inherent, but more of it will be accidental.
Wrapping type-erased shims around this that attempt to capture (some of) those semantics shines a light onto the problem. The effort raises good technical questions around whether the C layer can be improved. Where maintainers have approached that with an open mind, the results are positive for both C and Rust consumers. Difficult interfaces are a source of bugs; it’s always worth asking whether that difficulty is inherent or accidental.
Whilst it’s gotten a lot better in the -17 and -20 iterations, the fact that there was recently a doorstop book published solely on the subject of C++ initialisation semantics is pretty telling.
I really like what Herb Sutter’s doing around cppfront; I still wouldn’t use C++ unless I absolutely had to.