← Back to context

Comment by dzaima

4 days ago

Compilers at least allow specifying the standard to target, which solves the ISO revision issue. But breaking within the same -std=... setting is quite a bit more annoying, forcing either indefinite patching on otherwise-complete functional codebases, or keeping potentially every compiler version on your system, both of which are pretty terrible options.

Breaking within the same std, is something impossible to prevent in compiled languages with enough freedom in build.

Even the C ABI many talk about, most of them don't have any idea of what they are actually talking about.

First of all, it is the OS ABI, in operating systems that happened to be written in C.

Secondly, even C binary libraries have plenty of breakage opportunities within the same std, and compiler.

ABI stability even in languages that kind of promise it, is in reality an half promise.

Bytecode, or some part of the language is guaranteed to be stable, while being tied to a specific version, not all build flags fall under the promise, and not much is promised over the standard library.

Even other good examples that go to great efforts like Java, .NET or Swift, aren't fully ABI safe.

  • > First of all, it is the OS ABI, in operating systems that happened to be written in C.

    It may be per-OS (I wouldn't try linking Linux and NT object files even if they were both compiled from C by GCC with matching versions and everything), but enough details come from C that I think it's fair to call it a C ABI. Like, I can write unix software in pascal, but in order to write to stdout that code is gonna have to convert pascal strings into C strings. OTOH, pascal binaries using pascal libraries can use pascal semantics even on an OS that uses C ABIs.

  • It's certainly not impossible to write code that breaks, or modify a library in an ABI-incompatible way, but ABI stability, at least on Linux, does largely Just Work™. A missing older shared library can be quite problematic, but that's largely it.

    And while, yes, there are times where ABIs are broken, compiler versions affecting things would add a whole another uncontrollable axis on top of that. I would quite like to avoid a world of "this library can only be used by code compiled with clang-25" as much as possible.

  • This is honestly what pisses me off about the whole ABI thing. The ABI is defined by the OS, not the compiler. The compiler just implements the ABI, but somehow everyone lets their OS be defined by what a particular C/C++ implementation does. This then leads to FFI realistically only being possible by using a C/C++ compiler for interfacing, which defeats the point of an OS wide ABI.

    • I would consider the compiler to be part of the OS. You can't use an OS, if there is no way to create programs for it.

Assuming the code is position independent why can't the linker translate the ABI?

  • Maybe some things could be translated by a linker, but a linker can't change the size/layout of an in-memory data structure, and there's no info on what to translate from, even if info was added on what to translate to, anyway.

  • Data sizes, alignment, the way stuff is loaded into registers, all that can change.

    • My favourite weird ABI choice is: Who does what for a barrier? The barrier needs one party to do work for a full fence, but which party that should be doesn't matter... There can be an x86 FENCE over on the store side, or we can put the x86 FENCE on the load. We could do both but that's pointless, so don't do that. However if we do neither we haven't built a barrier and now there's probably a horrible bug.

I wish the additional proposak that would add Eust like editions with the cpp moduled were expected. So sad it didnt pass.