| C constructs normally map 1:1 in most languages. It's rare for a modern language to not be able to do all the things that C does. And, even if it's a little weird, it's not too hard to give out an escape hatch because the features aren't that advanced. C++ constructs--not so much. Does your language allow overloaded functions? If not, okay, you have to map that somehow (probably name mangling). Oh, your language has a different notion of inheritance than C++, well, now you need to map vtables somehow. And what does your system do about exceptions? Constructors/Destructors? Does it agree with the standard library about what a String is? What about memory allocation? etc. Even if the C++ ABI was perfectly described and standardized, mapping to it is always going to be error prone and clunky relative to the C ABI (which is just a lot simpler). If you want a good example, look at what it takes to use Vulkan via the C API/ABI--which is an exemplary implementation of an API, in my opinion. Look at the hoops you go through with loaders, structs that have type fields in them, extension fields so that you can add functionality without breaking compatibility, etc. All of that extra "gunk" is the kind of thing that C++ hides normally that gets terribly exposed when you have to cross an ABI boundary. |
I agree with the general gist of this, but:
• Java has no unions
• Java has no rectangular multidimensional arrays, although of course C arrays decay to pointers when passed anyway
• Java has no unsigned integer types, I imagine this is generally easily handled though
• Java has no const modifier, you'd need to keep track of that manually
• Java has no preprocessor, although of course this happens at the API level not the ABI level
• Java lacks bitfields but they're generally avoided in C APIs anyway, for good reason
• Probably worst of all, Java references are importantly different from C pointers
You're absolutely right though that the C ABI is a pretty good lingua franca ABI largely due to C being a pretty minimal language. No overloading, templates, garbage collector, or object model to worry about.