2017-02-17 20 views
8

Kilka dni temu pisałem coś jak poniżej:Dlaczego Visual C++ 2015 pozwala na std :: atomowe przypisanie?

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

Zestawione w Visual Studio 2015 Update 3 z VC++ 2015 kompilatora, nic złego pojawiło się.
Teraz mam zrekompilowane samo z GCC (5.4.0) na Ubuntu i mam błąd:

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

Mam ten sam błąd na ideone, zestaw do C++ 14 (nie wiem, co kompilator wersja, której używa).

Oczywiście zmiany kodu na następujący problem został rozwiązany z gcc:

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

moje pytania są następujące: 1.
kto ma rację (C++ 11 zgodny) tutaj, VC++ lub GCC? Wydaje się, że VC++ wywołuje konstruktor z bool, podczas gdy GCC wywołuje konstruktor kopiowania (usunięty).
2. Dla celów wartości domyślnej inicjalizacji atomowej w deklaracji klasy, czy jednolita inicjalizacja (powyżej) jest prawidłową/preferowaną metodą? Czy zamiast tego powinienem użyć makro ATOMIC_VAR_INIT (ugh!)?

struct A { 
    std::atomic_bool b = ATOMIC_VAR_INIT(false); 
}; 
+1

Zobacz http://stackoverflow.com/questions/21708606/why-does-an-in-place-member-initialization-use-a-kopia-constructor-in-c11. I na pytanie 2, nie używaj "ATOMIC_VAR_INIT", to głównie dla kompatybilności C11. – interjay

Odpowiedz

3

VC jest tu w błędzie. Pre-C++ 17 semantycznie kod X x = y oznacza wywołanie X tmp(y), po którym następuje wywołanie X(tmp) - tj. Istnieje semantycznie konstruktor kopii.

Podczas gdy wszystkie kompilatory, które znam, eliminują pośrednie wywołanie (standard dopuszcza to), program nadal jest źle sformułowany. Wygląda na to, że VC nie wymusza poprawnie semantyki.

W języku C++ 17 znaczenie semantyczne tego wywołania będzie wymagało tylko jednego inicjującego wywołania konstruktora, dzięki czemu kod stanie się dobrze sformułowany.

+0

Zastanawiam się, czy VC++ 2015 już implementuje coś z wersji C++ 17, to. – roalz

+0

@roalz, który nadal byłby nieprawidłowy w programie C++ 11. – Surt

+1

@Surt Sure, i o ile mi wiadomo, aktualizacja VC++ 2015 3 powinna mieć domyślny przełącznik/std: C++ 14 (jak w moim przypadku): https://blogs.msdn.microsoft.com/vcblog/2016/06/07/standards-version-switches-in-the-kompilator /. Wygląda na to, że jest to problem zgodności VC++. – roalz