53

I want to use std::atomic_bool because I want to have a boolean which is supposed to be accessed by different threads.

It's a static member Variable. The Problem is that I want to initialize it with false as the first state. Normally I would do it like that: std::atomic_bool World::mStopEvent = false;

But the problems seems to be that it doesn't take false as the constructor. So how I am supposed to initialize such a variable? I am using VS 2012.

0

4 Answers 4

41

This is a known issue in Visual Studio 2012 (known as VC11), you should vote on the existing Connect item so that Microsoft knows it affects more folks as they've deferred the fix.

Hi,

Thanks for reporting this bug. I'm Microsoft's maintainer of the STL, and I wanted to let you know that while this bug remains active in our database, it won't be fixed in VC11 RTM (VS 2012 RTM). All bugs are important to us, but some are more severe than others and rise to the top of our priority queue.

I'm copying-and-pasting this response across all of the STL's active Connect bugs, but the following terse comments apply specifically to your bug:

  • Yep, we're missing these constructors on atomic_bool, atomic_int, etc. (atomic<bool>, atomic<int>, etc. have them). 29.5 [atomics.types.generic]/7 says "There shall be named types corresponding to the integral specializations of atomic, as specified in Table 145, and a named type atomic_bool corresponding to the specified atomic<bool>. Each named type is a either typedef to the corresponding specialization or a base class of the corresponding specialization. If it is a base class, it shall support the same member functions as the corresponding specialization." which makes me really want to use typedefs (1 type is always simpler than 2 types), but I'll need to see if that would introduce any other issues.

I can't promise when we'll be able to resolve this bug, but we hope to do so as soon as possible (and I'll send another response when that happens) - our first opportunity will be the "out of band" release between VC11 and VC12 that Herb Sutter announced at the GoingNative 2012 conference.

Note: Connect doesn't notify me about comments. If you have any further questions, please E-mail me.

Stephan T. Lavavej Senior Developer - Visual C++ Libraries [email protected]

Basically, you'll need to use std::atomic<T> for now.

Sign up to request clarification or add additional context in comments.

Comments

37

Try this:

atomic_bool my_bool = ATOMIC_VAR_INIT(false); 

http://en.cppreference.com/w/cpp/atomic/ATOMIC_VAR_INIT

3 Comments

I think this is the best answer here, because it solves problem in the shortest way and without overhead. Also this solution is crossplatform, I compilled it in VS and Xcode.
Yes, compiles with Clang on Mac OS X, but with warning "braces around scalar initializer [-Wbraced-scalar-init]". Of course if you enabled it.
since C++11, deprecated in C++20 : (
32

PROBLEM:

You cannot use copy-initialization, because std::atomic_bool is not copy-constructible:

std::atomic_bool World::mStopEvent = false; // ERROR! 

In fact, the above is equivalent to:

std::atomic_bool World::mStopEvent = std::atomic_bool(false); // ERROR! 

However, you can use direct-initialization:

std::atomic_bool World::mStopEvent(false); 

At your wish, you may choose to use braces instead of parentheses:

std::atomic_bool World::mStopEvent{false}; 

BUG:

While copy-initialization is illegal no matter what compiler you choose, it seems that the implementation of the Standard Library shipped with VC11 has a bug that won't let you perform direct-initialization either.

So how I am supposed to initialize such a variable?

WORKAROUND:

As a possible workaround, you can provide a pair of static getter/setter wrappers that - respectively - set and return the value of the atomic boolean flag, but not before making sure it has been initialized at least once and not more than once to the desired initial value in a thread-safe manner (you can consider this some kind of lazy initialization):

#include <atomic> #include <mutex> struct World { static bool is_stop_event_set() { std::call_once(mStopEventInitFlag, [] () { mStopEvent = false; }); return mStopEvent; } static void set_stop_event(bool value) { std::call_once(mStopEventInitFlag, [value] () { mStopEvent = value; }); mStopEvent = value; } static std::atomic_bool mStopEvent; static std::once_flag mStopEventInitFlag; }; std::atomic_bool World::mStopEvent; std::once_flag World::mStopEventInitFlag; 

Now instead of accessing mStopEvent directly, its value shall be read through the is_stop_event_set() function:

#include <iostream> int main() { std::cout << World::is_stop_event_set(); // Will return false } 

Comments

2

How about:

std::atomic_bool World::mStopEvent(false); 

1 Comment

Same Error: error C2440: 'initializing' : cannot convert from 'bool' to 'std::atomic_bool' 1> No constructor could take the source type, or constructor overload resolution was ambiguous

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.