Boost logo

Boost :

Subject: Re: [boost] [Config] Support for switching between std:: and boost:: equivalents.
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2015-06-06 19:23:14


On Sat, Jun 6, 2015 at 11:54 PM, Edward Diener <eldiener_at_[hidden]> wrote:
> On 6/6/2015 8:26 AM, Andrey Semashev wrote:
>>
>> On Friday 05 June 2015 21:07:20 Edward Diener wrote:
>>>
>>> On 6/5/2015 6:35 PM, Andrey Semashev wrote:
>>>>
>>>> In general, you won't get away with just macros, as autolinking is only
>>>> present in MSVC & friends. This would also affect build system scripts.
>>>>
>>>> Suppose I'm a (Boost) library writer; the library has a compiled part
>>>> and
>>>> I'm writing a Makefile/Jamfile. If I'm using these macros, I still have
>>>> to know when to link and when not to link with Boost libs. This can be
>>>> rather tricky as not only compiler versions should be checked but also
>>>> their options; and it also needs to be in sync with Boost.Config. The
>>>> same happens when I'm a user of a (Boost) library that uses these
>>>> macros,
>>>> only it becomes more difficult to be in sync with Boost.Config. My point
>>>> is that since these macros don't actually abstract me away from the
>>>> configuration, why would I use them?
>>>
>>> They abstract you away from having to write complicated code which
>>> caters to whether or not a C++ standard library equivalent to a Boost
>>> library is available or not. They don't relieve the responsibility of a
>>> built library from naming itself in such a way that those linking with
>>> the library can do so successfully if auto-linking is not available.
>>
>> I think you missed my point above. It's not about naming the library, its
>> about the solution being incomplete to the point when you are not saved
>> much
>> by using these macros.
>
> I do not understand what sort of completeness you desire.

I think I explained it multiple times now. The macros don't abstract
away what implementation is being used - STL or Boost - because I have
to deal with linking anyway. That's why the solution is incomplete.

>> My current view on this is if you're writing a C++11 library it's fairly
>> logical for you to use STL11. No macros are needed for that. If you aim
>> for
>> C++03 compatibility, you should use STL03 and Boost where STL lacks
>> something.
>> Admittedly, this approach still has the library interoperability problem
>> but
>> at least your API and ABI are stable and do not depend on compiler
>> options.
>
> And suppose you want your library to work with either STL11 or STL03 ? Do
> you just decide that it is not possible so you have to choose one or the
> other ?

First, as I said, I don't see much point in this exercise. Second, if
this affects API/ABI then this severely harms my library usability, so
I definitely wouldn't do that. So yes, I decide which C++ level I will
target and write the code accordingly.

> That after all is what you are essentially saying a Boost library
> must do, is it not ?

I'm sorry, I didn't understand this question. I expressed my view on
the matter, based on my experience. It's not an official Boost policy,
if that's what you're asking.

> I find that irritating, not because I think the Boost libraries are any
> worse than their C++ equivalents, but because I see no reason why I should
> either have dependencies on other Boost libraries when I don't need to or
> that I have to cut off all end-users of my library compiler implementations
> if I choose just C++11 mode and STL11.

I explained why. You are free to ignore my reasoning, of course, but I
doubt your users will be happy in this case.

>> I understand your argument - after all C++ allows you to shoot yourself in
>> the
>> foot, so do your macros. But unlike C++ they don't make it really
>> difficult.
>> Maybe we just need a documented policy of use of these macros so that they
>> don't get misused. Maybe we need testing, when the library and tests are
>> compiled in different C++ modes. I don't know.
>
> I have developed a series of proof of concept tests for each of the
> libraries the macro system supports in either C++03 or C++11 mode. I have
> not tried to add PRs for those tests for each Boost library yet because my
> macro system is not in Boost.config 'develop' yet, and I don't want failings
> test for no reason.

If I understood you correctly, that's not the kind of tests I was talking about.

> Boost has implemented the notion that for libraries being built that the
> library name changes depending on whether or not the dynamic RTL or static
> RTL of the compiler implementation is being used. Also the library name
> changes depending on whether the library itself being built is a static or
> shared library. And there are a few more of these name manipulations which
> Boost enforces. I am simply arguing that we can come up with a means for
> doing the same on demand for C++ modes, not that we must do the same thing
> for C++ modes at all times.
>
> Let me give a very simple practical use case and this will illustrate what I
> am trying to discuss.
>
> I develop library EDS_LIB and it is a Boost library which must be built as a
> library and is not header-only, and my library uses regex in some interface
> it exports.
>
> I have a decision to make: do I use Boost.regex and therefore work in any
> C++ mode or do I use std::regex and therefore works only in C++11 mode (
> which I will assume supports the std::regex library ). Most people will say
> to use Boost.regex and be able to support any mode. Fair enough, but now
> EDS_LIB depends on Boost regex. If Boost ever goes to a more modular
> distribution all distribution of EDS_LIB must also include Boost regex.

Why? EDS_LIB would depend on Boost.Regex but not include it.

> OTOH if I choose C++11 mode the dependency on Boost.regex goes away, but now
> you need to compile whatever uses EDS_LIB in C++11 mode else my library is
> useless to you.

Correct.

> Now let's suppose, using my macro system, I can distribute my library as
> EDS_LIB in C++03 mode or EDS_LIB_C11 in C++11 mode. My exported interface
> using regex is:
>
> #include <boost/config/cpp/regex.hpp>
> #include BOOST_CPP_REGEX_HDR
> void EdsFunction(BOOST_CPP_REGEX_NS::regex & rx);
>
> Now if you compile your library or application in C++03 mode you link with
> EDS_LIB and you get its dependency on Boost.regex. If you compile your
> library or application in C++11 mode you link with EDS_LIB_C11 and you no
> longer have its dependency on Boost.regex. In your application or library
> you use my macro system in order to pass the correct regex in either case
> without worrying about which it is:
>
> #include <boost/config/cpp/regex.hpp>
> #include BOOST_CPP_REGEX_HDR
>
> BOOST_CPP_REGEX_NS::regex myregex("Some regular expression");
> EdsFunction(myregex);
>
> Where is the ABI problem in this case ? ( rhetorical question )

The ABI problem is right here. EDS_LIB, as it is distributed in a
Linux distro, is built in C++03, and it is incompatible with user's
code that is built in C++11. At least not in the way you describe.

My suggested approach would be to avoid both Boost.Regex and
std::regex in the binary interface - for example by passing strings in
the ABI. You can still use whatever regex you like in the API, or even
better - use concepts to accept any regex-like type, be that
std::regex, boost::regex or boost::xpressive::regex - whatever the
user happens to be using in his code.

> Multiply the dependency beyond just regex to a few other Boost libraries
> which have C++11 standard library equivalents and you can see how the
> problem of choosing builds up. Either you are going to have a number of
> dependencies on other Boost libraries in C++03 mode or you are again going
> to be unusable in C++11 mode to other modules not using C++11.

I'm sorry, I don't see what the number of dependencies have to do with
ABI stability.

> You are saying: choose, either your library may have a number of
> dependencies when building it in C++03 mode, or your library will not have
> those dependencies but will be usable only in C++11 mode.
>
> I am saying: having to choose is not acceptable in Boost as more compilers
> support C++11, but some either do not support C++11 or are not usable by
> end-users in C++11 mode.

It worked for me so far, I don't see the problem.

>> By the way, Boost is not the only project that attempts to maintain stable
>> ABI
>> regardless of the C++ mode. libstdc++ is also doing that, for example.
>
> How many other library dependencies does libstdc++ have ? Then ask yourself
> how many other library dependencies does any given Boost library have ? Have
> I made my point ?

No, I don't think you did. How the number of dependencies have any
relevance to API/ABI stability?


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk