Was ist ein sicherer Weg, um std::atomic_flag
in einem Klassenkonstruktor zu initialisieren?
Diese Frage scheint die gleiche Frage zu stellen, die ich stelle - außer hier beschwert sich der Fragesteller über ein Compiler-Problem.
Meine Frage bezieht sich auf den C ++ Standard selbst. Laut dieser Site ist das Initialisieren eines std::atomic_flag
mithilfe der Konstruktorinitialisierungssyntax erforderlich nicht spezifiziert.
Stimmt diese Information? Wenn ja, nehme ich an:
%Vor% ... ist ebenfalls nicht spezifiziert. Bedeutet das, dass wir std::atomic_flag
nicht als Membervariable einer Klasse verwenden können? Oder ist es sicher, wenn wir std::atomic_flag::clear()
innerhalb eines Klassenkonstruktors einfach aufrufen?
Der Wortlaut bezüglich der Verwendung von ATOMIC_FLAG_INIT
hat sich seit N3337 zu N3936 (dem aktuellen C ++ 14-Entwurf) geändert. Ersteres zeigt eine mögliche Verwendung in einem Kopierinitialisierungskontext des Makros ATOMIC_FLAG_INIT
in einem Beispiel, die nicht normativ ist und nichts über Verwendungen innerhalb anderer Initialisierungskontexte erwähnt.
N3936 verdeutlicht die Verwendung und listet die Verwendung der Kopierinitialisierung nicht mehr als Beispiel auf, sondern als Teil der Beschreibung selbst.
§29.7 / 4 [atomics.flag]
Das Makro
%Vor%ATOMIC_FLAG_INIT
soll so definiert sein, dass es verwendet werden kann initialisiere ein Objekt vom Typatomic_flag
in den Clear-Zustand. Das Makro kann in verwendet werden das Formular:
Es ist nicht angegeben, ob das Makro in anderen Initialisierungskontexten verwendet werden kann . Für ein vollständiges Objekt mit statischer Dauer sollte diese Initialisierung statisch sein. Sofern nicht mit
ATOMIC_FLAG_INIT
initialisiert, ist nicht angegeben, ob einatomic_flag
-Objekt einen initialen Zustand von set oder clear hat.
Die Begründung für diese Änderungen wird hier besprochen.
Sie haben also recht, dass die Verwendung des Makros in der Memberinitialisierungsliste nicht zuverlässig ist. Die Lösung besteht darin, einen Initiator für nicht statische Datenelemente oder brace-or-equal-initializer zu verwenden, um atomic_flag
zu initialisieren. Dann wird es in einem Kopierinitialisierungskontext initialisiert.
Der eigentliche Text des C ++ 11 Standards (naja, N1570 ) Definition von ATOMIC_FLAG_INIT
ist
7.17.8 Atomic Flag Typ und Operationen
...
Das Makro
ATOMIC_FLAG_INIT
kann verwendet werden, umatomic_flag
zu initialisieren klarer Zustand. Einatomic_flag
, das nicht explizit mit initialisiert wirdATOMIC_FLAG_INIT
befindet sich anfänglich in einem unbestimmten Zustand.BEISPIEL
%Vor%
Der C ++ - Standard verwendet das Wort initialize , um allgemein auf alle möglichen Arten zu verweisen, auf die eine Variable einen Anfangswert erhalten kann. Da es keine gegenteilige Formulierung gibt, habe ich die Absicht gelesen, dass atomic_flag guard(ATOMIC_FLAG_INIT)
und die Verwendung von ATOMIC_FLAG_INIT
in Konstruktorinitialisierungslisten ebenfalls gültig und nicht unspezifiziert sind. Ich denke, die Seite, die du zitierst, liest zu viel in das einzelne Beispiel. Beispiele in diesem Standard sind nicht normativ, und insbesondere, dass ein Beispiel zeigt, wie man etwas tun kann bedeutet nicht , dass dies der einzige akzeptable Weg ist, dies zu tun.