Std :: atomic_flag as a member variable

What is the safe way to initialize std::atomic_flag in a class constructor?

This question seems to ask the same question I am asking - moreover, here it asks a complaint about a problem with the compiler.

My question relates to the C ++ standard itself. According to this site, the initialization syntax of the constructor initializer std::atomic_flag not specified.

 std::atomic_flag static_flag = ATOMIC_FLAG_INIT; // static initialization, // guaranteed to be available during dynamic initialization of static objects. int main() { std::atomic_flag automatic_flag = ATOMIC_FLAG_INIT; // guaranteed to work // std::atomic_flag another_flag(ATOMIC_FLAG_INIT); // unspecified } 

Is this information correct? If so, I assume that:

 struct Foo { Foo() : flag(ATOMIC_FLAG_INIT) { } std::atomic_flag flag; }; 

... also not specified. So, does this mean that we cannot use std::atomic_flag as a member variable of a class? Or is it safe if we just call std::atomic_flag::clear() from the class constructor?

+8
c ++ c ++ 11
source share
2 answers

Words regarding the use of ATOMIC_FLAG_INIT have changed from N3337 to N3936 (current C ++ 14 project). The first shows the possible use of the ATOMIC_FLAG_INIT macro in a copy-initialization ATOMIC_FLAG_INIT in an example that is non-normative and does not mention anything about being used in other initialization contexts.

N3936 clarifies the use and no longer lists the use of copy initialization as an example, but as part of the description itself.

ยง29.7 / 4 [atomics.flag]

The ATOMIC_FLAG_INIT macro must be defined so that it can be used to initialize an object of type atomic_flag to a clear state. A macro can be used in the form:

  atomic_flag guard = ATOMIC_FLAG_INIT; 

It is not known whether the macro can be used in other initialization contexts . For a full object of static duration, this initialization must be static. If not initialized with ATOMIC_FLAG_INIT , it is not indicated whether the atomic_flag object atomic_flag initial state set or clear.

The rationale for these changes is discussed here .

So, you are right that using a macro in the list of member initializers cannot be justified. The solution is to initialize a non-static data element initializer or a sliding or peer-initializer to initialize atomic_flag . It will then be initialized in the context of copy initialization.

 struct Foo { std::atomic_flag flag = ATOMIC_FLAG_INIT; }; 
+8
source share

The actual text of the C ++ 11 standard (well, N1570 ) defines ATOMIC_FLAG_INIT

7.17.8 Type and operations of the nuclear flag

...

The ATOMIC_FLAG_INIT macro can be used to initialize atomic_flag for a clear state. atomic_flag , which is not explicitly initialized with ATOMIC_FLAG_INIT initially in an undefined state.

Example

  atomic_flag guard = ATOMIC_FLAG_INIT; 

The C ++ standard uses the word initialize to refer, as a rule, to all the different ways in which a variable can be assigned an initial value. Since there is no other wording to the contrary, I read the intention that atomic_flag guard(ATOMIC_FLAG_INIT) and the use of ATOMIC_FLAG_INIT in constructor initializer lists are also valid and not unspecified. I think the site you are quoting reads too much in one example. The examples in this standard are not normative, and, in particular, the example shows one way to do something does not mean that this is the only acceptable way to do it.

+2
source share

All Articles