consideri il seguente, dove abbiamo due file di ambito oggetti in diverse unità di traduzione, che è la solita installazione per indefinita-comportamento attraverso il fiasco ordine di inizializzazione:Gli atomici con ambito file sono soggetti al fiasco dell'ordine di inizializzazione?
a.hpp:
struct thing {
public:
thing(int value);
~thing();
int value() const;
static int count();
private:
int _value;
};
a.cpp:
#include "a.hpp"
#include <atomic>
namespace {
std::atomic<int> things;
}
thing::thing(int value) : _value(value) {
++things;
}
thing::~thing() {
--things;
}
int thing::value() const {
return _value;
}
int thing::count() {
return things.load();
}
b.cpp:
#include <iostream>
#include "a.hpp"
namespace {
thing static_thing(42);
}
void foo() {
std::cout << static_thing.value() << ' ' << thing::count() << '\n';
}
È questo il codice di un ordine di fiasco di inizializzazione tra il file ambito atomica things
in a.cpp e il file ambito static_thing
in b.cpp? Se no, perché no? In particolare, cosa rende speciale std :: atomic che rimuove quello che altrimenti sarebbe un chiaro fiasco di ordine init? C'è un particolare concetto che può essere chiamato per far rispettare questo con un asser statico? Qualcosa di simile:
static_assert(std::is_trivial<decltype(things)>::value, "file static counter is not trivial");
caso contrario std::is_trivial
, c'è un altro concetto e il tipo di caratteristica associata che modelli migliori questo?
Al contrario, esiste un fiasco di inizializzazione? Stesse domande su se sì, perché, o perché no.
mia breve ricerca in materia suggeriscono che data la garanzia che 'std :: atomica' devono essere specializzati, e atomiche specializzati hanno determinate proprietà, 'std :: atomica ' sarebbe proprio come un POD, per l'inizializzazione ordine, ad es nessun fiasco. Tuttavia, questo caso può anche essere risolto proprio come la maggior parte degli altri casi soggetti a init fiasco: ma dichiarando gli oggetti statici in ambito statico della funzione e sfruttando il fatto che gli oggetti con scope statica devono essere inizializzati prima della prima entrata in la funzione. –
L'ordine di costruzione di oggetti statici in traduzione diversa non è ancora specificato. L'uso di 'std :: atomic' non lo cambia. Perché ti aspetti che succeda? I compilatori particolari possono creare un'istanza per prima cosa sull'atomica, ma non è necessario. – Peter
@Peter perché std :: atomic ha un costruttore constexpr e viene inizializzato con una costante e ha un distruttore banale. Questo suggerisce che l'oggetto è effettivamente immortale. Poiché l'init statico ha luogo prima di qualsiasi init dinamico, e poiché non c'è nulla da fare per distruggerlo, è fondamentalmente immortale. Non vedo come possa esserci un ordine di inizializzazione fiasco w.r.t. qualsiasi cosa con inizializzazione dinamica. –
acm