Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Visual C++ 2015 allows std::atomic assignment?

A few days ago I've written something like the following:

struct A {
    std::atomic_bool b = false;
};

Compiled in Visual Studio 2015 Update 3 with its VC++2015 compiler, nothing wrong popped up.
Now I've recompiled the same thing with GCC (5.4.0) on Ubuntu and got the error:

use of deleted function 'std::atomic::atomic(const std::atomic&)

I got the same error on ideone, set to C++14 (not sure what compiler version it is using).

Of course changing the code to the following fixed the problem with gcc:

struct A {
    std::atomic_bool b { false };
};

My questions are:
1. who is is right (C++11 compliant) here, VC++ or GCC? It seems that VC++ calls the constructor from bool, while GCC calls copy constructor (deleted).
2. For the purpose of default value initializing an atomic in a class declaration, is uniform initialization (above) the correct/preferred way? Or should I use ATOMIC_VAR_INIT macro (ugh!) instead?

struct A {
    std::atomic_bool b = ATOMIC_VAR_INIT(false);
};
like image 449
roalz Avatar asked Feb 17 '17 14:02

roalz


1 Answers

VC is on the wrong here. Pre-C++17 semantically the code X x = y means a call to X tmp(y) followed by call to X(tmp) - i.e., there is a copy-constructor semantically called.

While all compilers I know if eliminate the intermediate call (standard allows that), program is still ill-formed. Looks like VC doesn't enforce semantics correctly.

In C++17, this call's semantic would change, and would require just a single initializing constructor call, thus the code will become well-formed.

like image 92
SergeyA Avatar answered Nov 04 '22 21:11

SergeyA