5

When I see this CPP Con 2017 webinar, Fedor Pikus says: "it has to be direct initialization"

enter image description here This is the link to the webinar.

What are the differences between these initialization methods? (and subsequently, why it has to be a "direct" initialization? why "indirect" initialization is "NOT"?)

// C++17 Compiler

#include <atomic>

class Example
{
    std::atomic<bool> m_b1 = false; // 1-h
    std::atomic<bool> m_b2{ false }; // 2-h

    static void doSomethng()
    {
        std::atomic<bool> b1 = false; // 1-f
        std::atomic<bool> b2{ false }; // 2-f
        std::atomic<bool> b3(false); // 3-f

        // Do something
    }
};
Amit
  • 645
  • 1
  • 3
  • 19
  • @HolyBlackCat , there is a link to the specific time tag in the webinar. It is a simple example of a: thread-1 Read; thread-2 Write scenario that atomic comes to help instead of a plain bool, – Amit Apr 10 '22 at 14:46

1 Answers1

7

std::atomic is not copyable or movable.

Before C++17, the copy-initialization std::atomic<int> x = 0; would first construct a temporary std::atomic<int> from 0 and then direct-initialize x from that temporary. Without a move or copy constructor this would fail and so the line doesn't compile.

std::atomic<int> x(0); however is direct-initialization and will just construct x with the argument 0 to the constructor.

Since C++17 there is no temporary and x will directly be initialized by a constructor call with 0 as argument in any case and so there is no issue with std::atomic being non-movable. In that sense the slide is now out-dated.

Even though the behavior is now the same for copy-initialization and direct-initialization in this case, there are still differences between the two in general. In particular direct-initialization chooses a constructor to initialize the variable directly by overload resolution while copy-initialization tries to find an implicit conversion sequence (possibly via converting constructor or conversion function with different overload resolution rules). Also, copy-initialization, in contrast to direct-initialization, does not consider constructors marked explicit.

Regarding the code snippet in the question. 1-h and 1-f are copy-initialization as above. 3-f is direct-initialization as above. 2-h and 2-f are direct-list-initialization, which behaves different from both others in some cases, but here it has the same effect as direct-initialization with parentheses.

Explaining all the differences between the initialization forms in general would take a while. This is famously one of the most complex parts of C++.

user17732522
  • 53,019
  • 2
  • 56
  • 105
  • I always thought that the expression `T x = 0;` would always try to call a constructor `T(int)` regardless of the class – MatG Apr 10 '22 at 14:53
  • So, since C++17, all methods are "Direct" and the same? – Amit Apr 10 '22 at 14:53
  • 2
    @Amit No, the first method is still copy-initialization and the second one direct-initialization. Just the meaning of what the copy-initialization does has changed. The two methods are still different for a few reasons. – user17732522 Apr 10 '22 at 14:55
  • @MatG See https://timsong-cpp.github.io/cppwp/n3337/dcl.init#16.6.2, but the temporary can be elided. It doesn't consider constructors at all, instead it will try user-defined conversion sequences. – user17732522 Apr 10 '22 at 14:56
  • @Amit: His answer *does* explain the difference. In pre-C++17, a temporary would be created that would be copied/moved from. In post-C++17, this doesn't happen anymore. It's the behavior of the expression that has changed, not whether that expression happens to be direct or copy initialization. That is, the thing called "copy initialization" no longer requires a "copy" under certain conditions. – Nicol Bolas Apr 10 '22 at 15:00
  • @Amit I think I mentioned the differences that are relevant here. Listing all of the differences between the two initialization forms will probably take a while. I guess the most important one is that copy-initialization doesn't consider constructors which are marked `explicit`. – user17732522 Apr 10 '22 at 15:02
  • 1
    @Amit Maybe https://stackoverflow.com/questions/1051379/is-there-a-difference-between-copy-initialization-and-direct-initialization has some more information on the general case. – user17732522 Apr 10 '22 at 15:05