On Sun, Aug 19, 2018 at 11:37 PM, Peter Dimov via Boost
Andrey Semashev wrote:
Our libraries should build into binaries that are suitable for linking with user's code in any C++ version, otherwise standard Boost binaries in Linux distributions will be compatible only with one C++ version, which is not practical.
I don't think that it's possible in general to support linking any C++ version to any other.
Suppose for instance that you have
struct X;
struct Y { void f( X const& x );
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
void f( X&& x );
#endif };
If you compile everything with C++03, it works. If you compile everything with C++11, it works. If you compile the library with C++11 and the user code with C++03, it works (barring other issues.)
But if you compile the library with C++03, and the user code with C++11, it doesn't. The user code tries to call Y::f(X&&), and it's not there.
I solved this in Boost.Log this way: struct Y { void f( X const& x ); #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) void f( X&& x ) { f_move(x); } #endif private: void f_move(X& x); };
Now the above is a trivial case, there are many other examples of code that could change depending on whether a feature is supported or not; and even when it 'works', it's still technically an ODR violation because the definition of Y is not the same.
Yes, I understand that not every case is as simple as the one above. That's why I'm asking for more details. And we have to accept that as soon as we enter this ABI stuff territory we're no longer in standard C++ land. We will most likely have to do dirty stuff, much like compiler writers do, to achieve compatibility. ODR issues are no longer relevant, as long as we're playing by compiler rules.
Being "ABI-portable" under a strict interpretation of the standard means that nothing in the user-facing headers is allowed to depend on whether a feature is supported or not. That's impractical. The only supported configuration, under said strict interpretation, is when everything is compiled with the same -std level. This applies even to libraries that do nothing differently by themselves, if they include a header-only library that does something differently.
In practice, the present situation with Boost.System is that you can link 03 to 11, 11 to 03, 03 and 11 to 14, but not 14 to 03 or 11. This was the best I could do.
Sorry, but I don't think this is acceptable. It prevents C++03 users from linking with system Boost.System (provided that the system Boost is compiled with default gcc options, which enable C++14). And there are strictly C++03 users out there. As a slightly different variant of the Boost.System2 solution, I can suggest building multiple Boost.System binaries, one per ABI we can support.