8

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);
};
Cœur
  • 37,241
  • 25
  • 195
  • 267
roalz
  • 2,699
  • 3
  • 25
  • 42
  • 1
    See http://stackoverflow.com/questions/21708606/why-does-an-in-place-member-initialization-use-a-copy-constructor-in-c11. And for question #2, don't use `ATOMIC_VAR_INIT`, that's mostly for C11 compatibility. – interjay Feb 17 '17 at 14:34

1 Answers1

2

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.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • I wonder if VC++2015 already implements something from the C++17 draft, then. – roalz Feb 17 '17 at 16:08
  • @roalz that would still be wrong in a C++11 program. – Surt Feb 17 '17 at 17:07
  • 1
    @Surt Sure, and as far as I know, VC++2015 update 3 should have /std:c++14 switch by default (as in my case): https://blogs.msdn.microsoft.com/vcblog/2016/06/07/standards-version-switches-in-the-compiler/. So it definitely seems a VC++ compliancy issue. – roalz Feb 17 '17 at 17:48
  • The Visual Studio team has taken the approach to implement C++14 and C++17 at the same time, so some features of C++17 have been implemented before some parts of C++14 . Looks like this is one of those areas where they have implemented C++17 already. – Sjoerd Feb 19 '17 at 11:59
  • @Sjoerd but it would be inconsistent with the default /std:c++14 compiler switch. I mean, if I specify the compiler to use c++14, IMHO it is WRONG to include partial stuff from c++17. And, because my case is ill-formed in C++14, I would expect VC++ to give an error, as GCC in c++14 mode. – roalz Mar 03 '17 at 13:21