3 ms·
I think your example is better evidence for my view. I remember this issue being mentioned in a CppCon talk: C++ 11 broke the ABI for STL (for efficiency as
by chubot 6y ago
I think your example is better evidence for my view. I remember this issue being mentioned in a CppCon talk: C++ 11 broke the ABI for STL (for efficiency as far as I remember), and the binary interface to libstdc++ changed as a result:
https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_a...
So the ABI can leak implementation details in nontrivial ways that library authors usually don't consider. It's better to have something explicit in the code, e.g. under extern "C".
The point is not that making a stable API for every language feature is impossible; just that it's hard, fragile, and maybe not be worth the effort. If you really want stability, then use fewer features more like C. There is probably some middle ground that's richer, but templates are known to cause problems.
Also see the release history here:
https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
- gpderetta 6y agoThe ABI break in libstdc++ has nothing to do with templates and it was not done by mistake. The layout of std::string changed to conform to the new standard; exactly the same thing would have happened if std::string was a C POD type, there is no way around that. In fact libstdc++ to this day still has the option to be compiled with the old ABI. There have been other minor ABI breaks, mostly to fix bugs, which affect only a small number of programs. Pure C libraries have exactly the same ABI stability issues caused by changes in layout of structures; to avoid this C libraries expose only opaque pointer sized handles to heap allocated objects. This is similar to C++ libraries only exposing pointers to virtual interfaces, but for high performance libraries, for example containers, this is not considered acceptable.
- chubot 6y agoThe point is that data layout is an implementation detail not part of the C++ API, and exposing that through shared libraries isn't a great idea. People do it, but it's a big mess and not particularly well documented. You can write conformant STL implementations that have completely different layouts. But the GNU one no longer had a valid layout, so it had to change. So when you expose libstdc++ as a shared library, you're exposing a bunch of details that aren't part of the C++ standard. If you write it in a header, then you can expect it to break callers via shared library. And templates must be in headers. This is a fundamental language issue. I don't use Rust, but the point is "making a stable ABI" will expose it to these sorts of problems, i.e. implementation details leaking on specific architectures, outside of the language. The projects that care about ABI stability, e.g. sqlite, don't expose layouts. They have only functions and not data in their headers.
- gpderetta 6y agoThis thread is getting confusing. Your original point was that for binary compatibility you write against the C ABI. I'm claiming that the C ABI has exactly the same fragile layout limitations and you can use the exact same workarounds in C++ (i.e. only expose pointers or make sure that your layout doesn't change). I'm also claiming that templates are a red herring and have very little to do with ABI.