Tuesday, August 16, 2011

C++11 standard library threads with MinGW

When trying to compile a C++11-enable application under MinGW, I ran into a strange error.

bougabouga.cpp:42:1: error: 'mutex' in namespace 'std' does not name a type

What ? Did my fellow programmer, who gave me this code, made a typo ? Or forgot to #include some files ? Not at all. Let's consider this simple piece of code :

#include <mutex>
std::mutex mutex;


Well, isn't that something simple. But still, it won't compile, complaining about this missing std::mutex we just added to the namespace chain. So let's see what happens in this header file :

On line 50, we may have found our culprit :

#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)

This macro wraps the entire source file. So, do we have them ? The answer is yes, we have this stdint macro, but no, we don't have GNU threads. Simply because MinGW has no support for these. So instead of issuing an error, this header file happily discards all its content. This is unexpected behaviour, but it will be helpful when the time comes to make a workaround for that.

And this workaround is, as always, to rely on good ol' boost. Many classes of the standard thread library (If not all, but I did not have read the specs) can be easily replaced with the boost ones. So, a fix header file would look like that :

#include <boost/thread.hpp>

namespace std {
  using boost::mutex;
  using boost::recursive_mutex;
  using boost::lock_guard;
  using boost::condition_variable;
  using boost::unique_lock;
  using boost::thread;
}



Isn't that pretty ? You don't even have to change your code. Now you have several options : either you add it to a central header file (If you're the StdAfx.h type, you're lucky), or you add it either manually or with a script to your source files, or you modify your gcc header files (they are useless anyway). Keep in mind that you will still need to add the boost thread library at link time.

You may want to follow me on twitter.

2 comments:

  1. The problem with this approach is that boost's thread library at present still does not perfectly mimic C++11's.

    C++11 uses std.chrono,
    Boost uses Boost.DataTime
    C++11 uses wait_until, wait_for, sleep_until and sleep_for
    Boost uses timed_wait

    It's a bit of a problem...

    ReplyDelete
  2. Thank you very much for this (kinda ugly but nevertheless perfectly working) fix. It saved me a lot of work. :)

    ReplyDelete