简体   繁体   English

std::atomic_flag 作为成员变量

[英]std::atomic_flag as member variable

What is a safe way to initialize an std::atomic_flag in a class constructor?在 class 构造函数中初始化std::atomic_flag的安全方法是什么?

This question seems to be asking the same question I'm asking - except here the asker is complaining about a compiler problem. 这个问题似乎在问我问的同一个问题——除了这里提问者抱怨编译器问题。

My question relates to the C++ standard itself.我的问题与 C++ 标准本身有关。 According to this site , initializing an std::atomic_flag using constructor initializer syntax is unspecified.根据此站点,未指定使用构造函数初始化程序语法初始化std::atomic_flag

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;
};

...is also unspecified. ...也未指定。 So, does this mean that we can't use an std::atomic_flag as a member variable of a class?那么,这是否意味着我们不能使用std::atomic_flag作为 class 的成员变量? Or is it safe if we simple call std::atomic_flag::clear() from within a class constructor?或者,如果我们从 class 构造函数中简单地调用std::atomic_flag::clear()是否安全?

The wording concerning use of ATOMIC_FLAG_INIT has changed since N3337 to N3936 (the current C++14 draft). 自N3337到N3936(当前的C ++ 14草案)以来,关于使用ATOMIC_FLAG_INIT的措辞已经改变。 The former shows a possible usage, in a copy-initialization context, of the ATOMIC_FLAG_INIT macro in an example, which are non-normative, and doesn't mention anything about uses within other initialization contexts. 前者在示例中显示了ATOMIC_FLAG_INIT宏的复制初始化上下文中的可能用法, ATOMIC_FLAG_INIT宏是非规范性的,并未提及有关在其他初始化上下文中使用的任何内容。

N3936 clarifies the usage, and no longer lists the copy-initialization usage as an example, but as part of the description itself. N3936阐明了用法,并且不再列出复制初始化用法作为示例,而是作为描述本身的一部分。

§29.7/4 [atomics.flag] §29.7/ 4 [atomics.flag]

The macro ATOMIC_FLAG_INIT shall be defined in such a way that it can be used to initialize an object of type atomic_flag to the clear state. 应以这样的方式定义宏ATOMIC_FLAG_INIT ,使其可用于将atomic_flag类型的对象初始化为清除状态。 The macro can be used in the form: 宏可以以下列形式使用:

  atomic_flag guard = ATOMIC_FLAG_INIT; 

It is unspecified whether the macro can be used in other initialization contexts . 未指定宏是否可以在其他初始化上下文中使用 For a complete static-duration object, that initialization shall be static. 对于完整的静态持续时间对象,该初始化应该是静态的。 Unless initialized with ATOMIC_FLAG_INIT , it is unspecified whether an atomic_flag object has an initial state of set or clear. 除非使用ATOMIC_FLAG_INIT初始化,否则未指定atomic_flag对象的初始状态是set还是clear。

The rationale for these changes is discussed here . 这里讨论了这些变化的基本原理。

So you're right that using the macro in the member initializer list cannot be relied upon. 所以你是对的,不能依赖在成员初始化列表中使用宏。 The solution is to use a non-static data member initializer, or brace-or-equal-initializer , to initialize the atomic_flag . 解决方案是使用非静态数据成员初始化程序或大括号或 atomic_flag 初始化来初始化atomic_flag Then it will be initialized in a copy initialization context. 然后它将在复制初始化上下文中初始化。

struct Foo
{
  std::atomic_flag flag = ATOMIC_FLAG_INIT;
};

The actual text of the C++11 standard (well, N1570 )'s definition of ATOMIC_FLAG_INIT is C ++ 11标准(嗯, N1570 )对ATOMIC_FLAG_INIT的定义的实际文本是

7.17.8 Atomic flag type and operations 7.17.8原子标志类型和操作

... ...

The macro ATOMIC_FLAG_INIT may be used to initialize an atomic_flag to the clear state. ATOMIC_FLAG_INIT可用于将atomic_flag初始化为清除状态。 An atomic_flag that is not explicitly initialized with ATOMIC_FLAG_INIT is initially in an indeterminate state. 一个atomic_flag未明确与初始化ATOMIC_FLAG_INIT最初处于不确定状态。

EXAMPLE

  atomic_flag guard = ATOMIC_FLAG_INIT; 

The C++ standard uses the word initialize to refer generally to all the various ways that a variable can be given an initial value. C ++标准使用单词initialize来指代变量可以赋予初始值的所有各种方式。 As there is no further wording to the contrary, I read the intent as being that atomic_flag guard(ATOMIC_FLAG_INIT) , and use of ATOMIC_FLAG_INIT in constructor initializer lists, are also valid and not unspecified. 由于没有相反的措辞,我将意图读作atomic_flag guard(ATOMIC_FLAG_INIT) ,并且在构造函数初始化列表中使用ATOMIC_FLAG_INIT也是有效的而不是未指定的。 I think the site you quote is reading too much into the single example. 我认为你引用的网站在单个例子中读得太多了。 Examples in this standard are not normative, and in particular, that an example shows one way to do something does not mean that that is the only acceptable way to do it. 在这个标准的例子是不规范的,特别是,这样的例子显示做一些事情并不意味着那就是做的唯一可接受的方式的一种方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM