Std mutex or boost mutex? Which is preferable? - c++

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.

Related

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

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.

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)

Is complete boost going to be included in C++0x?

Many utilities of boost have been included as part of extended C++ TR1 currently.
Is the complete boost library going to be included once the standard is officially out ? In other words, do I need boost library, if I have complete standard conforming C++11 compiler ?
If not then any reason for that (Reliability cannot be an issue; as far as I know it's written by many people from standard committee) ?
Boost is huge, and of generally high but still varying quality. A lot of the APIs - even the techniques and functionality - are quite "experimental" in the sense that they're still regularly modified as real-world feedback comes in. By way of contrast, the Standard is expected to get it right and need minimal revision, especially when that breaks backwards compatibility.
The standard for review for Standard libraries is much higher than boost's, which is not to say that many boost libraries wouldn't meet the bar - just that many wouldn't too, and that the review process itself is time consuming. There are terrific programmers coordinating and contributing to boost, but they naturally focus their time on their own development interests and things they see as more relevant, so if something is a little specialised, doesn't appeal to their coding style, etc. it may not receive the same scrutiny. The Standard library needs to be scrutinised much more thoroughly as the consequences of change are so much more painful.
While portability is a factor in acceptance of a library into boost, it's not a hard and fast requirement, where-as compiler vendors are expected to make the Standard library run on all C++ compilers, so taking boost more or less as-is and expecting the functionality to be universal on Standard-compliant compiler vendors would put a huge workload on those vendors.
No, in fact very few parts of Boost are "included" in the C++0x revisions to the C++ Standard Library. The parts that are "included" are some of the most commonly used parts of Boost, though.
Really, "included" isn't correct anyway: there are many differences between the Boost libraries and the corresponding additions to the C++ Standard Library. Further, the Boost libraries continue to grow and evolve; the C++0x Standard Library is now finished.
No, Boost is not going to be included in its entirety in C++0x.
Parts of Boost will be, like boost::shared_ptr, Boost.Array, and a couple of other things. But most of Boost is not being included.

C++0x threading

With the advent of threading facilities in the STL for the new C++ standard (C++0x), will it be better to change existing code that is using POSIX threading or even Windows threading to use STL threading?
You could always hedge your bets... write your own simple threading API that is just featureful enough to do what your application needs to be done, and change your code to target your threading API only. Then you can implement the internals of your custom threading API using Windows or Posix or STL or whatever, and change the implementation whenever you need to without having to touch your entire codebase each time.
By doing it that way, you could start with the STL implementation, and then if it turns out that e.g. Windows has a difficult-to-resolve problem using that, you could just include an alternate Windows-API implementation inside my_threading_api.cpp (inside of an #ifdef WIN32) and you'd be back in business.
A great deal will depend on how much you care about portability, and how much you're taking advantage of features your native API may provide that the standard library doesn't. The standard library threading is sufficiently similar to POSIX that (at least offhand) I can't think of much you'd gain by staying with POSIX (and due to the similarity, porting to use the standard library should usually be pretty easy).
Windows threading is enough different that you're more likely to run into something that will be non-trivial to port to using the standard library, and even at best porting will probably be non-trivial.
Don't change unless you really need it. I assume that your existing code is working well.
There's no telling how long it will be before the C++0x library features are commonly supported, so the answer might well depend on how tied to a particular compiler you might want to be.
You might also want to consider a framework or library that works on top of the native or C++0x library implementation, such as Boost Threads or the Intel Threading Building Blocks and let that library handle the details of whether it's using C++0x features or platform APIs.
It depends.
C++0x threading isn't widely supported yet (I think GCC implements it, but MSVC doesn't, and I don't know when they're planning to add that support, but I might suspect they consider it a low priority feature)
If your code works as it is, why change it?
For new C++ applications, and assuming compiler support, I'd go with C++0x threads, simply because they're standard, and it's a much nicer API than either Win32 or POSIX threads.

Preparing for the next C++ standard

The spate of questions regarding BOOST_FOREACH prompts me to ask users of the Boost library what (if anything) they are doing to prepare their code for portability to the proposed new C++ standard (aka C++0x). For example, do you write code like this if you use shared_ptr:
#ifdef CPPOX
#include <memory>
#else
#include "boost/shared_ptr.hpp"
#endif
There is also the namespace issue - in the future, shared_ptr will be part of the std, namespace - how do you deal with that?
I'm interested in these questions because I've decided to bite the bullet and start learning boost seriously, and I'd like to use best practices in my code.
Not exactly a flood of answers - does this mean it's a non-issue? Anyway, thanks to those that replied; I'm accepting jalfs answer because I like being advised to do nothing!
The simple answer is "do nothing". Boost is not going to remove the libraries that got adopted into 0x. So boost::shared_ptr will still exist. So you don't need to do anything to maintain portability.
Of course, once 0x is here, a lot of code can be simplified, cleaned up and optimized, but since it's not yet here, that work can't really begin. All you can do is make sure your code will still compile when 0x hits... and it should, just like that. Boost isn't going to delete half their libraries. (I'm not guessing. They've stated this on their mailing list before)
(and if you want to switch to the standard shared_ptr, I'd say it's probably easier to just do a simple search/replace when the time comes. Replace #include <boost/shared_ptr.hpp> with #include <memory>, and boost::shared_ptr with std::shared_ptr)
Or of course, you can just decide on the project that you're going to keep using Boost's shared_ptr. Just because it's been added to the standard library doesn't mean you have to use it, after all.
Nothing will need to be done because of namespaces. If you want to use the boost implementation you will still use the boost namesapce.
I don't think they would venture into breaking compatibility in such a big way with a previous version.
See my previous similar question here: what will happen with the overlapping portion of boost once C++0x becomes mainstream?
But of course if you do using namespace a lot in your code you may have some overlapping definitions. You'll have to go back to specifying the namespace explicitly on each use.
The best way to use shared parts between C++0x and Boost is to use the Boost.TR1, i.e; the implementation if the Technical Report already accepted. Boost.TR1 will use the implementation provided by the compiler when it is available, and the provided by Boost otherwise. This was the main goal of Boost.TR1
"The TR1 library provides an implementation of the C++ Technical Report on Standard Library Extensions. This library does not itself implement the TR1 components, rather it's a thin wrapper that will include your standard library's TR1 implementation (if it has one), otherwise it will include the Boost Library equivalents, and import them into namespace std::tr1. "
No we don't, as of yet, given the facts that:
support for C++0x is not yet upto the mark across the various platforms (we need) and
that it is yet to be declared a standard officially
But yes, we do use Boost as and when required (but of course, only after a release has gone through a sanitation phase do we use it) just like any other third party library that we use. Also, we use the source form on a as-needed basis.
There is however an effort towards more stringent adoption of the driving principles in product design phase (e.g. move-ctor etc).
There is definitely going to be some work when C++0x gets standardised; but that will also require us to move on to some of newer compilers (vc10?) and moving on to a new compiler is always a task in it's own.
You may actually always prefer using the Boost version for a long time. Especially if you need to compile on multiple platforms.
The Boost libraries are ported and tested on multiple platforms and behave the same there (most of the time.)
The first vendor implementations of the new C++ libraries may still contain minor bugs and performance differences just like it was such a mess when STL and the std namespace were added.