This is such a common fallacy. C exposes lower-level memory management, but to then say "oh now you have pointers you can implement anything" is a push.
If you need to implement virtual tables and function pointers, you'd use C++ - there's no need to reinvent the wheel.
Besides software engineering is about focusing on the intrinsic complexity, and using languages and tools to mitigate the incidental complexity.
Tenuous - if you are willing to implement objects yourself then you could use C sure, but I don't think that means the language "lets you use OO". It's like you could also probably implement algebraic datatypes in C using unions and structs, but would that mean "C lets you use algebraic datatypes"? I would strongly argue no.
All our languages are Turing-complete. None actively prevent any sort of programming,
Thus, to meaningfully claim that a language supports some programming technique, it has to automate it to some appreciable degree. C manifestly does not; it automates nothing but stack frames and register allocation. Every detail is hand-coded, with every opportunity to make trivial, hard-to-spot mistakes that nothing but exhaustive testing can bring to your attention.
Agreed, I think that the code itself should be readable through better names, with the comments being a bonus rather than critical to the understanding of the code.
Yes, exactly. Clang emitted IR especially has a lot of (C/C++)-specific junk. If you look past that clutter, it's not too bad.
I think the best way to learn to read IR is to look at super-minimal examples, and then you'll be able to tell which parts of larger IR files are relevant.
Hey, author of the post here. Do I think the C++ API is important? For most languages no. The OCaml bindings in my case were almost sufficient, but I planned to do some memory fences and other operations in my language that the OCaml bindings didn't have.
In hindsight, it's probs better to choose OCaml bindings and then link in any special instructions you need from C++ if you need to.
Regarding this post in particular, I chose to document everything in terms of the C++ API as that's the native API. You can use any of the other bindings, and just translate the syntax across to your language.
If you need to implement virtual tables and function pointers, you'd use C++ - there's no need to reinvent the wheel.
Besides software engineering is about focusing on the intrinsic complexity, and using languages and tools to mitigate the incidental complexity.