Boost logo

Boost :

Subject: Re: [boost] [Config] Support for switching between std:: and boost:: equivalents.
From: Edward Diener (eldiener_at_[hidden])
Date: 2015-06-06 23:39:57


On 6/6/2015 7:23 PM, Andrey Semashev wrote:
> 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.
>

I have repeated again and again that for built libraries, as opposed to
header-only libraries, a system of distinct names for the same library
depending on whether the library is compiled in C++03 mode or C++11 mode
can solve this problem.

I know that you think that solving this problem is the responsibility of
my macro solution, and therefore the macros are not worthwhile using
unless I solve it in my implementation. That's your right and I am not
going to bother to argue with it. I think we are just at a point of
basic disagreement on this issue.

>>> 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.

How in the world would EDS_LIB depend on Boost.Regex but not have it
part of the distribution of EDS_LIB if we go with a modular Boost
distribution where EDS_LIB could be distributed by itself with its
dependencies ?

>
>> 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.

EDS_LIB distribution is not distributed for C++11 use. For that my
previously mentioned EDS_LIB_C11 is distributed with its dependencies
for C++11 use.

>
> 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.
>

I know you are not kidding but I consider your solution "not optimal".
Your solution is that two perfectly usable versions of regex exist but I
need to manufacture another. Needless to say that is not my idea of
programming in this situation.

>> 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?

What does API/ABI stability mean in this context to you ? We are
probably discussing this at cross-purposes because my interpretation of
what it means is not what you mean.


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