WIll Boost have a version with a modern-C++ "cutoff"? - c++

With C++17 now published, even more of Boost's libraries are now covered by the standard library: optional, variant, any, ASIO (in the Networking TS), coroutines (in a TS) and more. This, in addition to the gobs and gobs of Boost stuff already in the standard, see this answer. I realize that some of the standardized versions have slightly different design space choices than Boost's, but essentially it's the same.
Given this fact, are there or have there been plans to release an alternative version (or just - a new mainline version) of Boost which:
Foregos most or all of these features as Boost libraries
Lets the rest of the Boost code rely on their availability in the standard library
Lets the Boost code rely on the language being at least C++17, to make life easier and the code more scrutable to developers
?
If not - is this because of the importance of the Boost design choices? Too much hassle? Fear of "project bifurcation"?
Note: This is an informative question, so please don't provide your opinion or whether this would be a good idea or not.

Boost has better implementation than many currently existing implementations of standard C++ library.
Note that:
Some issues might be fixed in the latest versions of compilers, I didn't recheck everything before writing this post.
Boost is quite conservative and support many old compilers. Even if the latest compiler has everything fixed, older version still have to work.
With regards to Unicode, I assume C++ programs will try to follow UTF-8 Everywhere.
Boost.Filesystem vs <filesystem>
Windows has no support for Unicode in both C/C++ runtimes e.g. you cannot switch standard library to Unicode-aware narrow character set (UTF-8). As the result std::filesystem::path always assumes non-unicode encoding when used with char sequences. There is std::filesystem::u8path for this, but writing std::filesystem::path p = some_char_sequence imo is way too easy. Any codebase that uses std::filesystem and supports Windows will have to battle this constantly.
Boost.Filesystem allowed user to specify locale to be used for path objects. Boost.Locale could be used to create UTF-8 locale on Windows, eliminating this issue. Std.filesystem does not allow you to do this.
Boost.System vs <system_error>
On Linux with glibc:
std::error_category::message is not thread safe, although it should be. Boost.System at least tries to provide thread-safe implementation for every platform.
System category is not able to test for equivalency with standard error conditions.
On Windows (MSVC) it is broken in multiple places:
Error messages returned by std::system_category have annoying "\r\n" at the end, which does not happen anywhere else. Boost.System explicitly trims those.
Comparing addresses of std::error_category does not work for generic and system categories if used cross-dll. Boost.System never had this issue.
Error message is returned using current user enconding (never UTF-8). Technically this is allowed since standard does not specify encoding used here, but it doesn't help anyone. Although Boost.System did the same (should not be mentioned here?).
Standard error categories are static-local singletons and thus register destructor through std::atexit. When category is accessed for the first time from another atexit handler. This might be a problem and can cause deadlocks (as any implicit locking). I had experience with this in the past.
System category is not able to match WinAPI error codes against POSIX error codes the same way Boost.System does this (something that was the whole point of this facility in the first place).
On MSVC12 (Visual Studio 2013) comparing error categories does not work across dlls. This is one of compilers supported by Boost. Boost.System had no such issues.
The sad part about <system_error> is that <filesystem> and future networking library (ASIO) both rely on it heavily, so both get a little bit broken on Windows.
Boost.Thread vs <mutex>, <condition_variable>, <shared_mutex>.
Until recently on Windows and MSVC std::condition_variable and std::mutex could cause deadlock when instantiated in a dll due to using lazy initialization internally. With MSVC14 (Visual Studio 2015) this should be fixed at least for std::mutex since it was rewritten to use SRW locks internally, but I am not sure about condition variables. MSVC12 (Visual Studio 2013) definitely has a lot of bugs here.
If you need a reader-writer lock, it might be very important to know if it favors readers or writers. Standard std::shared_mutex does not allow you to specify this behavior and according to the original proposal this was done because there is an algorithm that allows implementation to favor neither and try to prevent starvation of both (somewhat "fair" lock). Original implementation e.g. boost::shared_mutex follows this algorithm and is not based on pthread_rwlock_t (which usually favors readers due to requirements of POSIXas std::shared_mutex. Imo this means std::shared_mutex has a poor implementation on many systems. Although Boost implementation is not the fastest one either.

Related

Std mutex or boost mutex? Which is preferable?

What is the real difference between std::mutex and boost::mutex? Which one is faster in terms of implementation and compilation? Are both of them portable?I read my questions related to it but there is no clear mention of difference . std mutex is supported only since c++11 so the older compilers dont support it . Are boost mutex supported by older compilers or not? If the foremost condition requires the code to be portable , then what should be prefered?
As a default choice you should prefer std::anything to boost::samething because it's a part of standard library and hence is more portable since it doesn't introduce external dependency.
You can't really compare std::mutex and boost::mutex in general because there is no one and only std::mutex, it's implementation depends on the standard library implementation that you are using which usually is a part of your toolchain.
There might be a case when you discover using empirical evidence that std::mutex you are using is in some regard "worse" than boots::mutex. In this case it might be reasonable to switch to it, but only if it's really justified and you have an actual evidence (e.g. performance measurement) of that. Even then it seems like a last resort. It might be better to switch to a different standard library implementation or to a different toolchain or upgrade your current one if possible.
Consider boost as a laboratory for prototyping std features. Many std facilities were originally implemented on boost. The difference is that std takes care of consistency and forward compatiblity, while boost targets new horizons. Nothing prevents boost from applying breaking changes in forth coming versions, but it also provides answers to more questions than std. My personal preference is std first - when possible - and boost next - when needed. I generally avoid pre c++11 platforms, unless I am forced to face.
# std::mutex for me every time, for the reason #Henri states it is (obviously) part of the C++ standard so you can rely on it being available everywhere.
Using boost, on the other hand, means that you have to link against the boost library. While this is widely available and offers a number of handy extra features it's quite heavyweight and you wouldn't want to pull it in just for this.
Also, std::mutex may be faster. The cross-platform nature of boost means that things that rely on OS support (which would include mutexes) can sometimes be less efficient. But this would not be a major factor in my thinking.
But if measuring performance is important to you, you should run your own benchmark. You can do this (roughly) over at (say) Wandbox - they support the boost library there.
The focus of Boost is trying new techniques and introducing new capabilities. The focus of the C++ standard is specifying requirements in a way that (in most cases) can be implemented portably. A number of features from boost have found their way into the C++ standard, but were often changed quite a bit in that transition - to improve portability, sometimes improve reliability, etc.
If your implementation (compiler and library) is C++11 or later, and you intend to not to port to older implementations, then definitely use std::mutex. It is part of the standard, from 2011, so preferable. No need to rely on third-party libraries. You will only need boost if you need bleeding edge features of boost that the C++ standard does not support (which means things other than mutex).
Some exceptions to the above: there are some features of boost (including related to threading and mutexes) that haven't made their way into a C++ standard, and some features in the C++ standard that are not in boost.
If you need to use (or support or port to) an older implementation, then consider using boost::mutex. You will, in most cases, need to install a version of boost separately, with your chosen implementation (some compiler versions have shipped with a version of boost, but don't rely on it). If there isn't a version of boost that works with your compiler/library, then (to state the obvious) you will not be able to use boost::mutex.
Boost has had the thread library (which includes mutex) since about version 1.25.0, which dates from late 2001. Which suggests boost is an option if your compiler is no older than (rough guess) early 2000s.
If you need to support an implementation that is significantly older than the early 2000s, then you may be out of luck using boost::mutex, and will need to resort to other libraries/frameworks or get your hands dirty writing OS-specific code.

Is c++11 thread platform independent?

I searched for lots of questions and answers, but I really couldn't figure out this issue. Yesterday I have tried C++11 thread on Windows in a Visual C++ project and it works fine.
Does that mean we can use C++11 threads on every platform that has a compiler with C++11 support? Are there any reasons not to use this thread instead of pthread or Windows thread (depending on the platform)?
The C++ 11 thread library still uses threads from the OS and relies on them but it is abstracted in a good way so you will experience almost no differences. The behavior is different only in the detail and you will almost not notice them (only on edge cases and/or on failure). There might be still some platforms out there which don't support everything from std::thread (even in 2015, e.g. on some specific / exotic mobile platforms).
From the C++ Standard:
30 Thread support library
Some functions described in this Clause are specified to throw
exceptions of type system_error (19.5.6). Such exceptions shall be
thrown if any of the function’s error conditions is detected or a call
to an operating system or other underlying API results in an error
that prevents the library function from meeting its specifications.
Failure to allocate storage shall be reported as described in
17.6.5.12.
C++11's thread mechanisms are intended to be cross-platform like any other feature of standard C++. From my understanding, all major compilers intend to support the C++ standard to the best of their ability which means supporting the threading library.
It really depends how well the compiler supports it. I would imagine GCC / VS /Intel have pretty good support by now but then if you are targeting some exotic platform that might not necessarily be the case.
That's been the case with the STL for a while now - it's mostly portable, but it really depends on the implementation.
Just because it's in the standard does not mean it will magically work, even though the chance of it working is much higher than if it was not in the standard.
There will still be other implementations - pthread, boost, whatever. Which one you use depends on your personal preferences, your requirements, etc, etc.
Yes, it is platform independent. It can be (and often is) implemented as wrapper for pthreads, so basically it can be pthreads with different API.

How to find Boost libraries that does not contain any platform specific code

For our current project, we are thinking to use Boost framework.
However, the project should be truly cross-platform and might be shipped to some exotic platforms. Therefore, we would like to use only Boost packages (libraries) that does not contain any platform specific code: pure C++ and that's all.
Boost has the idea of header-only packages (libraries).
Can one assume that these packages (libraries) are free from platform specific code?
In case if not, is there a way to identify these kind of packages of Boost?
All C++ code is platform-specific to some extent. On the one side, there is this ideal concept of "pure standard C++ code", and on the other side, there is reality. Most of the Boost libraries are designed to maintain the ideal situation on the user-side, meaning that you, as the user of Boost, can write platform-agnostic standard C++ code, while all the underlying platform-specific code is hidden away in the guts of those Boost libraries (for those that need them).
But at the core of this issue is the problem of how to define platform-specific code versus standard C++ code in the real world. You can, of course, look at the standard document and say that anything outside of it is platform-specific, but that's nothing more than an academic discussion.
If we start from this scenario: assume we have a platform that only has a C++ compiler and a C++ standard library implementation, and no other OS or OS-specific API to rely on for other things that aren't covered by the standard library. Well, at that point, you still have to ask yourself:
What compiler is this? What version?
Is the standard library implementation correct? Bug-free?
Are those two entirely standard-compliant?
As far as I know, there is essentially no universal answer to this and there are no realistic guarantees. Most exotic platforms rely on exotic (or old) compilers with partial or non-compliant standard library implementations, and sometimes have self-imposed restrictions (e.g., no exceptions, no RTTI, etc.). An enormous amount of "pure standard C++ code" would never compile on these platforms.
Then, there is also the reality that most platforms today, even really small embedded systems have an operating system. The vast majority of them are POSIX compliant to some level (except for Windows, but Windows doesn't support any exotic platform anyways). So, in effect, platform-specific code that relies on POSIX functions is not really that bad since it is likely that most exotic platforms have them, for the most part.
I guess what I'm really getting at here is that this pure dividing line that you have in your mind about "pure C++" versus platform-specific code is really just an imaginary one. Every platform (compiler + std-lib + OS + ext-libs) lies somewhere along a continuum of level of support for standard language features, standard library features, OS API functions, and so on. And by that measure, all C++ code is platform-specific.
The only real question is how wide of a net it casts. For example, most Boost libraries (except for recent "flimsy" ones) generally support compilers down to a reasonable level of C++98 support, and many even try to support as far back as early 90s compilers and std-libs.
To know if a library, part of Boost or not, has wide enough support for your intended applications or platforms, you have the define the boundaries of that support. Just saying "pure C++" is not enough, it means nothing in the real world. You cannot say that you will be using C++11 compilers just after you've taken Boost.Thread as an example of a library with platform-specific code. Many C++11 implementations have very flimsy support for std::thread, but others do better, and that issue is as much of a "platform-specific" issue as using Boost.Thread will ever be.
The only real way to ever be sure about your platform support envelope is to actual set up machines (e.g., virtual machines, emulators, or real hardware) that will provide representative worst-cases. You have to select those worst-case machines based on a realistic assessment of what your clients may be using, and you have to keep that assessment up to date. You can create a regression test suite for your particular project, that uses the particular (Boost) libraries, and test that suite on all your worst-case test environments. Whatever doesn't pass the test, doesn't pass the test, it's that simple. And yes, you might find out in the future that some Boost library won't work under some new exotic platform, and if that happens you need to either get the Boost dev-team to add code to support it, or you have to re-write your code to get around it, but that's what software maintenance is all about, and it's a cost you have to anticipate, and such problems will come not only from Boost, but from the OS and from the compiler vendors too! At least, with Boost, you can fix the code yourself and contribute it to Boost, which you can't always do with OS or compiler vendors.
We had "Boost or not" discussion too. We decided not to use it.
We had some untypical hardware platforms to serve with one source code. Especially running boost on AVR was simply impossible because RTTI and exceptions, which Boost requires for a lot of things, aren't available.
There are parts of boost which use compiler specific "hacks" to e.g. get information about class structure.
We tried splitting the packages, but the inter dependency is quite high (at least 3 or 4 years ago).
In the meantime, C++11 was underway and GCC started supporting more and more. With that many reasons to use from boost faded (Which Boost features overlap with C++11?). We implemented the rest of our needs from scratch (with relative low effort thanks to variadic templates and other TMP features in C++11).
After a steep learning curve we have all we need without external libraries.
At the same time we have pondered the future of Boost. We expected the newly standardized C++11 features would be removed from boost. I don't know the current roadmap for Boost, but at the time our uncertainty made us vote against Boost.
This is not a real answer to your question, but it may help you decide whether to use Boost. (And sorry, it was to large for a comment)

Migrating from Boost to the Standard Library for C++11

I am new user of the boost library. I find my self thinking more about adopting boost for a number of reasons. From what I can tell, it seems that the boost library is a sort of skunkworks sandbox where various C++ TR features for upcoming standardization are tried out before being adopted by the C++ committee - think boost::filesystem and boost::regex,
As an example, I was trying out some of the C++11 regex features in visual studio via the #include header - this worked great until I ported to a target power pc platform, which, at the time used CodeSourcery's GCC 4.7.3. Unfortunately, I realized that at run-time, that much of the regex implementation was incomplete or empty (even thought it compiled) - With a bit of homework, I should have realized this beforehand, however now that GCC 4.8.x is out, the implementation is part of the v3 standard C++ library so it is a different story now.
In an ideal world, the standard library should be like developing for Java - write once, deploy everywhere - but that is not a reality. I would eventually like to move to the standard library implementation rather than Boost's regex and filesystem implementations.
My question given the above regex history, is how should developers use boost, is it possible to do a simple search and replace of the boost headers and namespaces when the features are adopted by the standard library or are there more many things to consider. I would like to use pure C++11 code without dependency on 3rd party libraries.
The amount of work required to move from a Boost library to its C++11 conterpart depends on the degree of C++11 conformance of a particular Boost library. In the simplest case it can be a matter of including another set of headers and using another namespace.
In a more complicated case, Boost library may have some subtle incompliancy with C++11 (eg. in Boost.Thread V1 ~thread used to call detach()) - such things might "silently" break the code correctness, but they are easy to fix.
Finally, Boost library may implement funcionality that doesn't exist in C++11 (eg. boost::bind can be extended using get_pointer function). Apparantly, porting such a code to C++11 would be quite not trivial.
Let's begin with your statement
I would like to use pure C++11 code without dependency on 3rd party
libraries.
It is clear that this is not possible now. You will have to use 3rd party libraries for any non-trivial program.
Unfortunately, C++ with Boost is not a platform also. You need 3rd party libraries to do things available out of the box in languages like Java, C#, Python etc.
So, you have to select libraries according to your requirements: performance, supported platforms, multithreading etc.
Again, Boost shouldn't be your default choice. It is not that useful now as it was 10 years ago. Most of must have stuff went into C++ standard library already.
If you support existing C++ codebase, find the best C++ library for your needs (e.g. re2 for regex). If you start a new project, I would suggest using Qt as a platform.
A "simple" way to migrate usage may be to use preprocessor defines to define a "Using Boost" directive. By putting all boost code in an #if-#else and carefully writing the code to not break (or at least have expected results) for sections that do not have a C++11 equivalent. You can simply not provide a definition for "Using Boost" before at the beginning of your code and C++11 features would be used instead.
See this and this
One link points to an old stackoverflow question, the other to an interesting talk performed by Stephan Lavavej

When should you use an STL other than the one that comes with your compiler?

I was curious about STL implementations outside of what's packaged with gcc or Visual Studio, so a quick Google search turned up a few results, such as:
Apache stdcxx
uSTL
rdeSTL
Under what circumstances should one use an alternative standard template library?
For instance, Apache's page has a list including items such as "full conformance to the C++ standard" and "optimized for fast compiles and extremely small executable file sizes". If it's so good, why wouldn't it replace libstdc++?
For the sake of completeness, here are some of the other STL implementations:
STLPort
STXXL (which is sort of special purpose, meant for large data sets that won't fit in memory)
Dinkumware (commercial)
SGI STL
libstdc++ (GCC's implementation)
I never had to use an STL version other than the one packed with the compiler. But here are some points that come into my mind.
Thread-safety: The STL from apache provides a compile switch to turn on/off some thread-safety features.
Localization: Again the STL from apache comes with nice support for many different locales.
Data structures: You might need a basic_string implementation that is based on COW (copy-on-write) and the STL version that came with your compiler doesn't offer that.
Non-standard extensions: Particular features you like from some other STL implementations. For example, hash_map (and related) versions from Dinkumware (which ships with Visual Studio) have a significantly different design from hash_map (and related) from STLPort.
Binary issues: Constraints in some environment (embedded software) due to code size. In such case, if you don't need the whole STL it could be interesting to use a reduced version.
Performance: What if you discovered, after profiling, that the "other" STL implementation gives you significant better performance for a particular application. (With so many details concerning algorithms and data structures this could actually be possible.)
Debug mode: Some STL implementation provide nice features for debugging. For instance, checking ranges of iterators.
I sometimes use STLPort rather than the STL that ships with Visual Studio. Back when VC6 was supported the STL that shipped with it was buggy and so using STLPort (or another STL) made a lot of sense (especially if you were building multi-threaded code).
Now it's often more about performance (size or speed). For example, the STL that ships with VS2008 isn't that friendly in a multi-threaded situation as it uses locking around locale objects which causes things that you wouldn't expect to synchronise across threads. (See here Convert a number to a string with specified length in C++ for details of one example of this).
Third parties can implement improved versions of STL that attempt to offer various things, such as smaller size, faster execution, etc. You might choose one of these alternative implementations because you want one of those attributes of their implementation. You might also choose one of them when doing cross-platform development because you want to avoid running into differences in behavior between the gcc and Visual Studio versions of your product (as just one example).
There is no need to wait for a new release of a compiler with a bundled implementation of STL in order to reach out for a fresh implementation of it if you have specific needs.
I've never had a need to use an alternative STL, but I could envision some scenarios where it might be useful to use, for example, the Apache version, if you need small executables because you're developing for an embedded platform.
Another reason might be to use an STL version that guarantees certain things which are not necessarily guaranteed by the standard. For example, to ensure you have non-COW strings so you can write thread-safe code.
STLport has what they call a "power debug mode" that does a whole slew of run-time checking for "the correctness of iterators and containers usage". Helps catch a number of errors that would not be immediately obvious. I highly recommend use of STLport while debugging and testing.
The C++ standard library can be implemented in variety of ways. Some implementers try to cope with modern ideas. So, using an optimized implementation may result in faster and smaller executables.
Take SCARY for example. Some implementers didn't do it yet, although it reduces the bloat of STL to a great extent. When you do the following:
vector<int> f;
vector<int, MyAllocator> s;
size_t fc = count(f.begin(), f.end(), SomeValue);
size_t sc = count(s.begin(), s.end(), SomeOtherValue);
An "old" implementation could produce two different count functions in the result executable, because the type of f is not the same as of s. Thats because the iterator type depends on the type of the vector itself, although it doesn't need to be like that. A better idea is to separate the type of the iterator in a separate class, and provide a typedef in vector, and the compiler would produce one count only. That was just an example, but I think there are more to say about the quality of some implementations.
Aside from the reasons already given, I could imagine using a different STL due to debugging support or as a way to guarantee I was not relying on vendor extensions.
It would also be a first step in testing whether a library I was shipping worked well on other platforms.
Folks mentioning STLport have cited performance and portability, but there's also a pretty good debug mode available. I think that's a great reason to be using a different STL, if your current compiler's library is limited in this way.
Aaand ... it looks like Max and I tied on mentioning debugging! ;^)~
One reason is for better thread-safety. I was using the default STL that came with Visual Studio (VC6 infact) then had to shift to STLPort as it had much better thread-safety.
We are currently using STLPort - external implementation of STL because we have to use (for various reasons) quite old Microsoft Visual C++ 6.0 compiler (1998 release date) and compiler supplied library (by Dimkunware) is of course very out of date.
Debugging has been mentioned by several people, in terms of the ability to switch on extra diagnostic information, however another important aspect is that if you're using the platform's own STL then you may get a better experience in the debugger. This is especially true if you're using Visual Studio which has visualisers for all the standard containers.
STLPort has support for files bigger than 2GB through std::fstreams. Visual Studio 2005/2008 cannot handle files bigger than 2GB.
You can test your STL implementation by displaying: std::numeric_limits<std::streamsize>::max()
Both MSVC++ and GNU g++ come with pretty good implementations of the C++ Standard Library, but there are compilers that don't, and if I had to support such compilers I would look for a 3rd party implementation of STL.