4 ms·
There is a solution to the additive API problem, but C and C++ do not allow it. The solution is to create separate modules like x11/v1, x11/v2, etc. which live
by slaymaker1907 6y ago
There is a solution to the additive API problem, but C and C++ do not allow it. The solution is to create separate modules like x11/v1, x11/v2, etc. which live in the same distribution. It is therefore permitted for module A to use x11/v1, module B to use x11/v2, and module C to use both A and B (you may need to also provide a shim between common types like a to_v1 function). In this setup x11_v2 probably exposes many of the same bindings as v1, but that is ok since it is low effort to wrap a function or to re-export a private module with the common bindings.
This doesn't work in C/C++ due to how the C ABI works. There needs to be an easy way to say that even though A and B both have a foo function they are not the same foo and a way for module C to use both versions of foo by renaming one of them in its source. This is the greatest sin of the C ABI in my opinion, not even the lack of overloads.
- captainmuon 6y agoI think if you use dynamic linking, it is in principle possible for module A to use v1 internally, and for module C to use v2, and neither to know about the other. But you can't use global objects, and you can't share objects from the internal libraries between modules. And the dynamic linker on Linux at least tries to reuse symbols, so it doesn't work by default. This was a big problem in the Gtk2 / Gtk3 transition, where you could not use both in the same process. I think there is a flag to prevent symbol reuse, though.
- account42 6y agoThis is a solved problem with symbol versions and symbol aliases, which are used extensively by libaries like glibc that care about providing a stable ABI. For C++, GCC and Clang also provide the abi_tag attribute: > The abi_tag attribute can be applied to a function, variable, or class declaration. It modifies the mangled name of the entity to incorporate the tag name, in order to distinguish the function or class from an earlier version with a different ABI; perhaps the class has changed size, or the function has a different return type that is not encoded in the mangled name. This was introduced to allow mixing pre-C++11 and post-C++11 std::string and std::list implementations in one libstdc++.so but is more general. The other solution is of course a new SOVERSION but that does not allow two different versions to be used in the same process as ELF symbols are a process-global namespace.