web-dev-qa-db-de.com

Ist die Initialisierung lokaler statischer Variablen in C ++ 11 threadsicher?

Ich weiß, dass dies eine häufig gestellte Frage ist, aber da es so viele Varianten gibt, möchte ich sie gerne erneut angeben und hoffentlich eine Antwort erhalten, die den aktuellen Stand widerspiegelt. So etwas wie

Logger& g_logger() {
    static Logger lg;
    return lg;
}

Wird der Konstruktor der Variablen lg garantiert nur einmal ausgeführt?

Ich weiß aus früheren Antworten, dass dies in C++ 03 nicht der Fall ist. In C++ 0x Draft wird dies erzwungen. Aber ich hätte gerne eine klarere Antwort auf

  1. Ist das thread-sichere Initialisierungsverhalten in C++ 11-Standard (nicht Entwurf) abgeschlossen?
  2. Wenn das oben Gesagte zutrifft, sind sie in den aktuellen Versionen der populären Compiler, nämlich gcc 4.7, vc 2011 und clang 3.0, ordnungsgemäß implementiert?
192
Ralph Zhang

Der relevante Abschnitt 6.7:

eine solche Variable wird initialisiert, wenn die Deklaration zum ersten Mal durchlaufen wird. Eine solche Variable gilt nach Abschluss ihrer Initialisierung als initialisiert. [...] Wenn die Steuerung die Deklaration gleichzeitig eingibt, während die Variable initialisiert wird, muss die gleichzeitige Ausführung auf den Abschluss der Initialisierung warten.

Dann gibt es eine Fußnote:

Die Implementierung darf keinen Deadlock in Bezug auf die Ausführung des Initialisierers verursachen.

Also ja, du bist in Sicherheit.

(Dies sagt natürlich nichts über den späteren Zugriff auf die Variable durch die Referenz aus.)

172
Kerrek SB

Erwähnenswert ist auch die --fno-threadsafe-Statik. In gcc:

Geben Sie keinen zusätzlichen Code aus, um die in C++ ABI angegebenen Routinen für die thread-sichere Initialisierung der lokalen Statik zu verwenden. Mit dieser Option können Sie die Codegröße in Code, der nicht threadsicher sein muss, geringfügig reduzieren.

Schauen Sie sich auch den alten Thread an Sind funktionsstatische Variablen in GCC threadsicher?

15
Denis Glotov