L’inizializzazione della variabile statica locale è thread-safe in C ++ 11?

So che questa è una domanda frequente, ma poiché ci sono così tante varianti, mi piacerebbe re-dichiararlo, e spero che abbia una risposta che rifletta lo stato attuale. Qualcosa di simile a

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

Il costruttore della variabile lg è garantito per funzionare una sola volta?

So dalle risposte precedenti che in C ++ 03, questo non lo è; in bozza C ++ 0x, questo è applicato. Ma mi piacerebbe una risposta più chiara a

  1. In C ++ 11 standard (non in bozza), il comportamento di inizializzazione thread-safe è stato finalizzato?
  2. Se quanto sopra è sì, nelle attuali versioni più recenti di compilatori popolari, vale a dire gcc 4.7, vc 2011 e clang 3.0, sono implementati correttamente?

La sezione pertinente 6.7:

tale variabile viene inizializzata al primo controllo del tempo attraverso la sua dichiarazione; tale variabile è considerata inizializzata al completamento della sua inizializzazione. […] Se il controllo immette la dichiarazione contemporaneamente durante l’inizializzazione della variabile, l’esecuzione simultanea deve attendere il completamento dell’inizializzazione.

Poi c’è una nota a piè di pagina:

L’implementazione non deve introdurre alcun deadlock attorno all’esecuzione dell’inizializzatore.

Quindi sì, sei al sicuro.

(Questo non dice nulla sul successivo accesso alla variabile attraverso il riferimento.)

– Vale la pena menzionare anche -fno-threadsafe-statics. In gcc:

Non emettere il codice aggiuntivo per utilizzare le routine specificate nell’ABI C ++ per l’inizializzazione thread-safe delle statistiche locali. È ansible utilizzare questa opzione per ridurre leggermente la dimensione del codice nel codice che non deve necessariamente essere thread-safe.

Inoltre, dai un’occhiata al vecchio thread Le variabili statiche della funzione sono thread-safe in GCC?