7 ms·
This is a strange complaint that seems to reduce to C not having a well defined ABI. Of course it doesn't. C implementations do. This isn't really any differen
by dleslie 5y ago
This is a strange complaint that seems to reduce to C not having a well defined ABI.
Of course it doesn't. C implementations do. This isn't really any different than most other languages, but feels different because C doesn't have a blessed implementation that all other implementations must interact with.
That's a strength. It means C is found on esoteric microcontrollers as well as powerful modern desktops. That wouldn't work as well as it could if the ABI were uniform on all targets and implementations.
And yes, it can act as a protocol. It's the simplest way to access host ABI communication without understanding it.
- titzer 5y agoEsoteric microcontrollers don't need an ABI. ABIs are for static and dynamic linking, and in the microcontroller world, there isn't a whole lot of linking going on. It's very common to statically compile everything into one single flash image, with libraries being in source form. E.g. this is the case in the Arduino ecosystem.
- dleslie 5y agoThey still have an internal ABI used when static linking; aligning structures, laying out data sections, function call behavior, and so forth. C's flexibility/ambivalence in this regard is why it's preferred on those architectures.
- titzer 5y agoOne could consider static linking in this scenario just an optimization for incremental builds with separate compilation of source files; it's not really used to, e.g. link a library that has no source. In that sense, it's just an implementation detail that's leaked from a build system that notionally recompiles from source but has unwisely exposed the units of its caching system. Microcontroller programs are also pretty small; it's not difficult to load the whole program into memory on a workstation and compile the whole thing together. This is how Virgil (circa 2006) worked.
- dleslie 5y agoYou still have to make choices that may conflict with languages that strictly define their internal binary representations. And I definitely have received .o files from vendors.
- uxp100 5y agoI don’t think there is anything wrong with the single compilation unit approach, but every embedded project I’ve been on on the last 10 years has used static linking, which doesn’t preclude ending up with a single flash image. 10 years is about the last time I worked on a non-arm based project, so that could be a factor (the pic compiler I was familiar with at that time did not have a linker, and I’m not sure if the avr compiler I used did)
- stefan_ 5y agoThis. The intention for C was never to have an immutable, well defined super-portable ABI so that all the people who like to feel superior for not using C can paper over their C use in comfort. It just so happened that C is so simple that it is some 80% along the way to an ABI between systems.
- dzaima 5y agoI'd argue it's more like only 40% of the way to a proper ABI; sizeof(long) varying on the same CPU architecture is just horrible. Sure, it wasn't meant to be an ABI, but, well, it is. And we're stuck with it. And oh how nice would it be if we weren't.
- lelanthran 5y ago> sizeof(long) varying on the same CPU architecture is just horrible. On the other hand, `sizeof (int8_t)` is the same size no matter which architecture you are running on. If you, as the programmer, are depending on the bit-width of an integer type, C has got you covered mostly.
- dzaima 5y agoi mean, if sizeof(int8_t) varied, noone would even try to use C as a lingua franca. I, as the programmer, would never expose unknown width integer types, but other things still will, and I'll be forced to interact with them. Allowing such things to even be present in an ABI is just horrible.
- acuozzo 5y ago> On the other hand, `sizeof (int8_t)` is the same size no matter which architecture you are running on. EDIT: See account42's reply below. ORIGINAL COMMENT: No, it's not. CHAR_BIT is not required to be 8 and sizeof (int8_t) is not required to be 1. Hell, int8_t is not even required to be present in <stdint.h>, but int_least8_t is.
- dzaima 5y ago
- aidenn0 5y ago> This is a strange complaint that seems to reduce to C not having a well defined ABI. The complaint isn't that C lacks a well defined ABI, it's that e.g. x86_64-unknown-linux-gnu potentially lacks a stable ABI.
- dleslie 5y agox86_64 linux has long had a stable ABI. Any given target for C is as stable as the host developer wishes it to be.
- Rusky 5y agoThis is less about stability and more about clarity. The most unchanging and unbroken ABI in the world can still be a huge mess of undocumented special cases only really accessible via the combination of the platform's C compiler and its headers.
- Rusky 5y agoThe complaint seems to be less that C as a whole has a lot of ABI implementations, and more that those individual implementations themselves are also not very well-defined, even on the biggest platforms. That is, in principle the strength of supporting a wide variety of platforms has absolutely nothing whatsoever to do with the quality of implementation on those platforms.
- dleslie 5y agoLinux and Windows have had rock solid ABIs for decades now. Just about any system-appropriate 32bit binary will run on either, if the necessary system libraries are present.
- Rusky 5y agoAgain, this really doesn't seem related to the article. Nobody is saying those ABIs are making breaking changes, but that they are poorly documented and full of edge cases that make it difficult to reliably produce one of those system-appropriate binaries, short of just giving up and pulling in the platform's entire C toolchain.
- dleslie 5y agoOutside of only the most trivial microcontrollers you're going to find edge cases numbering proportional to the complexity of the system. Software complexity is hard. I'm not sure what's the goal in complaining about that. Just venting?
- Rusky 5y agoJust because it's hard doesn't mean it's already been done in the best possible way. Finding and documenting flaws (or "venting") is a great step towards improving. Seriously though what on earth is your point here? This is an incredibly thorough article on an interesting, difficult subject, with a lot of room for different technical choices. Do you just not like the tone?
- pornel 5y agoMany of these implementations are needlessly weird and underspecified. C happens to work despite these quirks due to sheer amount of hours everyone puts to work around C's critical but vague notion of an ABI. The fact that the biggest compilers don't quite agree on the ABI for the most popular desktop CPU is not a success of C's portability or flexibility, just a historical quirk caused by the C language moving slower than evolution of the hardware and needs of operating systems.
- dleslie 5y agoIt's not a quirk of C; it's a failure of the vendors and their partners to appropriately coordinate. This outcome happened _despite_ the best efforts of toolchain developers to provide harmony.
- pornel 5y agoThe C standard working group is the avenue for vendors/partners to coordinate. Whenever the standard settles on "implementation defined" that's a confirmation that the vendors failed to reach an agreement (often because the standardization effort happened too late, and they've already implemented diverging solutions, and nobody wants to break their userbase).
- deleted 5y ago[deleted]
- bregma 5y agoAn operating system has an ABI. Programs compiled from C source use the OS's ABI. There is no "C ABI". The very premise of TFA is fundamentally incorrect, and there is no way to reach a valid conclusion from an incorrect premise.
- falcor84 5y agoI think your argument kinda agrees with TFA, as it's stating that C's nature as the defacto ABI for all interoperability on all operating systems is in conflict with it trying to, at the same time, still be a programming language. It would be very nice to have a non-C ABI.
- bregma 5y ago> C's nature as the defacto ABI... It would be very nice to have a non-C ABI. > An operating system has an ABI. Programs compiled from C source use the OS's ABI. There is no "C ABI". I'm having difficulty getting these two ideas to reconcile.
- deleted 5y ago[deleted]
- riking 5y agoOn many platforms, such as FreeBSD and macOS, the application-exposed ABI for tasks such as "open a file" or "validate this x.509 TLS certificate" mandates that you link to a shared library and call into it using the C calling convention. (libc and Security.framework, respectively.) Linux is unique in that you can hand-write assembly to perform a system call and have it work across OS upgrades. FreeBSD does not have stable syscall numbers: open() must be a libc call.
- thatsnotc 5y agoThe application-exposed ABI for those tasks mandates that you execute a few assembly instructions to make a syscall (and perhaps also do some work that the libc normally wraps around the actual syscall for you). ABIs deal with machine instructions, that's why the "binary" is in there. The OS-provided API for the tasks are libc and Security.framework. Do you have any suggestions for a better API?