I'll try to be less aggressive this time, sorry, writing that last post left a bad taste in my mouth.
Chris wrote:
Obviously there are multiple versions, but why is that the case? Because the binary interfaces for C++ are unstable. This is nowhere near as big of a problem in C, so it's not an inherent problem of public interfaces to be this bad. Ergo, the C++ language has a problem that makes interfaces unstable.
...
Sorry, I mean the ABI of C++ libraries. Yes, the general C++ ABI itself is set.
Oh, that's fine then. I assumed we were both talking about the language ABI itself, but apparently that's not the case. For the rest of this conversation I'm going to use the term "API version" to refer to a library compatibility target, and "language ABI" to refer to the symbol mangling and calling convention of a shared library.
I don't really think C++ makes it easy to change the API version of a library on accident. I
do think that there's a linker problem, but I think it's exactly the same one that C has, which it does, when glib updates and breaks old userspace programs. In a reasonable world, either glib versions would be packaged with each application, or old glib API versions would continue to be used forever, even if they only function as a translation layer to the latest version of glib. Java has this basically
done with Maven, but C and C++ both don't really determine much of the linking process, and in practice, GCC presents the same fundamental problems for both of them.
So having to keep track of several individual versions of C++ libs isn't because of regular breakages from using C++ interfaces? Then what is it because of?
Normal backwards-incompatible library API version changes.
No, C doesn't have this problem anywhere near as badly as C++ does. There's a reason why if you want a stable ABI for a library you use C, rather than C++. Yes, it can happen with C, but it's more prone to happening when using C++ because extra details end up in a binary interface that don't otherwise need to be in it. It takes more work to keep a C++ interface stable compared to a C interface, because the latter better separates the implementation from the interface.
I don't really think this is the language's fault, and I don't think it's true that C++ has it significantly worse than C, either. With C libraries, the binary ABI of a given version of a given library contains
too little information about things like types for how low level it is. This is basically a security hazard. It's easier to break binary compatibility with C++, but only when the behavior of your library already changed and you shouldn't be using the changed version with something that wasn't meant for it.
Ironically, your video even suggests what GNU/libstdc++ does. "Avoid breakage by turning it into accretion. Old and new can coexist." That's exactly what the symbol versioning accomplishes. If an interface needs to break, the old interface is kept with its old version and the new interface is added with a new version. Under Windows, you get an entirely new DLL that has that interface updated. Under Linux, the shared library just gains a new interface that coexists with the old one.
The accretion he's referring to is to basically consider the API version part of the identity of the library. You wouldn't link "SDL2", you'd link "SDL2 2.0.4". If that exact API version of that library isn't found on the system, your program won't run. It won't try to run with 2.0.3 or 2.0.5, only 2.0.4. No backwards compatible version changes like semver tries and fails to provide. This is very different from adding new interfaces to existing shared libraries, and still different from what Windows programs generally do which packages the correct version of every library with every program (except for the 20 DX redistributables I have installed).
I'm asking for clarification on what you meant.
Things like dynamic arrays and variants should by all means be part of the language spec. For some reason they're not. I don't know why they're not, but it's insane to consider dynamic arrays and variants to be extensions of a program instead of extensions of the language. If the C++ standard library only included utilities like i/o streams instead of fundamental data structures like dynamic arrays I would get the comparison to third party libraries like SFML, but the fact that it's so low level means that it can't be expected to operate at the same level. Again, I
do think this is stupid, and those things should be part of the language, not the standard library, but that's the way things stand right now.