2159. atomic_flag initialization

Section: 32.8 [atomics.flag] Status: C++14 Submitter: Alberto Ganesh Barbati Opened: 2012-05-24 Last modified: 2016-02-10

Priority: Not Prioritized

View all other issues in [atomics.flag].

View all issues with C++14 status.

Discussion:

32.8 [atomics.flag]/4 describes the ATOMIC_FLAG_INIT, but it's not quite clear about a couple of points:

  1. it's said that ATOMIC_FLAG_INIT "can be used to initialize an object of type atomic_flag" and the following example:

    std::atomic_flag guard = ATOMIC_FLAG_INIT;
    

    is presented. It's not clear whether the macro can also be used in the other initialization contexts:

    std::atomic_flag guard ATOMIC_FLAG_INIT; 
    std::atomic_flag guard {ATOMIC_FLAG_INIT};
    
    struct A { std::atomic_flag flag; A(); };
    A::A() : flag (ATOMIC_FLAG_INIT); 
    A::A() : flag {ATOMIC_FLAG_INIT};
    

    Please also note that examples are non-normative, according to the ISO directives, meaning that the wording presents no normative way to use the macro.

  2. it's said that "It is unspecified whether an uninitialized atomic_flag object has an initial state of set or clear.". I believe the use of "uninitialized" is inappropriate. First of all, if an object is uninitialized it is obvious that we cannot assert anything about its state. Secondly, it doesn't address the following cases:

    std::atomic_flag a; // object is "initialized" by trivial default constructor
    std::atomic_flag a {}; // object is value-initialized
    static std::atomic_flag a; // object is zero-initialized
    

    strictly speaking a trivial constructor "initializes" the object, although it doesn't actually initialize the sub-objects.

  3. it's said that "For a static-duration object, that initialization shall be static.". Considering the following example:

    struct A
    {
      A(); // user-provided, not constexpr
    
      std::atomic_flag flag = ATOMIC_FLAG_INIT;
      // possibly other non-static data members
    };
    
    static A a;
    

    The object a.flag (as a sub-object of the object a) has static-duration, yet the initialization has to be dynamic because A::A is not constexpr.

[2012, Portland]

We would like to be able to allow more initialisation contexts for example:

  1. C struct
  2. C++ constructor initializer-list

However we need further input from experts with implementation specific knowledge to identify which additional contexts (if any) would be universally valid.

Moved to open

[2013, Chicago]

Move to Immediate, following review.

Some discussion over the explicit use of only copy initialization, and not direct initialization. This is necessary to allow the implementation of atomic_flag as an aggregate, and may be further reviewed in the future.

Accept for Working Paper

Proposed resolution:

[This wording is relative to N3376.]

Change 32.8 [atomics.flag]/4 as follows:

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. 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. It is unspecified whether an uninitialized Unless initialized with ATOMIC_FLAG_INIT, it is unspecified whether an atomic_flag object has an initial state of set or clear. [ Example:

atomic_flag guard = ATOMIC_FLAG_INIT;

end example ]