Using C++11 futures: Nested calls of std::async crash: Compiler/Standard library bug?

After experiencing crashes when introducing nested calls of std::async in my real program, I was able to reproduce the problem in the following minimum example. It crashes often, but not always. Do you see anything what goes wrong, or is it a compiler or standard library bug? Note that the problem remains if get() calls to the futures are added.

#include <future>
#include <vector>

int main (int, char *[])
{
    std::vector<std::future<void>> v;
    v.reserve(100);
    for (int i = 0; i != 100; ++i)
    {
        v.emplace_back(std::async(std::launch::async, [] () {
            std::async(std::launch::async, [] { });
        }));
    }

    return 0;
}

I observe two different kinds of crashes: (in about every fifth run)

  • Termination with "This application has requested the Runtime to terminate it in an unusual way."
  • Termination after throwing an instance of 'std::future_error', what(): Promise already satisfied.

Environment:

  • Windows 7
  • gcc version 4.8.2 (i686-posix-dwarf-rev3, Built by MinGW-W64 project), as provided by Qt 5.3.2
  • Command line call: g++ -std=c++11 -pthread futures.cpp
  • Compiled and run on two independent machines

Option -pthread? Could it be that in my environment for some reason the option -pthread is silently not taken into account? I observe the same behavior with and without that option.


Solution 1:

Since this answer is still "unanswered," after talking with some people from Lounge<C++>, I think I can say that it's pretty obvious from the comments that this is due to an implementation error either on MinGW/MinGW-w64's or pthread's part at the time. Using gcc 4.9.1, MinGW-W64, the problem does not appear anymore. In fact, the program above appears to compile and run correctly even on a version earlier than 4.8.2 with POSIX threading.

I myself am not an expert, my guess is that the exact trip-up happens when the program appears to try to write to the same promise twice, which, I think, should be a big no-no, as an std::async should write its result only once (again, I'm not sure if I'm right here, and other comments and edits will most likely clarify).

Also, this may be a related problem: std::future exception on gcc experimental implementation of C++0x