On Sat, Jun 6, 2015 at 11:54 PM, Edward Diener
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
#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
#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?