web-dev-qa-db-fra.com

L'initialisation de la variable statique locale est-elle thread-safe en C ++ 11?

Je sais que la question est souvent posée, mais comme il existe de nombreuses variantes, je voudrais la reformuler et obtenir une réponse reflétant l’état actuel. Quelque chose comme

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

Le constructeur de la variable lg ne doit-il être exécuté qu'une seule fois?

D'après les réponses précédentes, je sais qu'en C++ 03, ce n'est pas le cas. dans le brouillon C++ 0x, ceci est appliqué. Mais j'aimerais une réponse plus claire à

  1. En standard C++ 11 (pas de brouillon), le comportement d'initialisation thread-safe est-il finalisé?
  2. Si tel est le cas, dans les dernières versions actuelles des compilateurs populaires, à savoir gcc 4.7, vc 2011 et clang 3.0, sont-elles correctement mises en œuvre?
192
Ralph Zhang

La section pertinente 6.7:

une telle variable est initialisée la première fois que le contrôle passe par sa déclaration; une telle variable est considérée comme initialisée à la fin de son initialisation. [...] Si le contrôle entre la déclaration simultanément alors que la variable est en cours d'initialisation, l'exécution simultanée doit attendre la fin de l'initialisation.

Ensuite, il y a une note de bas de page:

L'implémentation ne doit pas introduire de blocage dans l'exécution de l'initialiseur.

Alors oui, vous êtes en sécurité.

(Cela ne dit évidemment rien sur l'accès ultérieur à la variable via la référence.)

172
Kerrek SB

--fno-threadsafe-statics mérite également d'être mentionné. En gcc:

N'émettez pas de code supplémentaire pour utiliser les routines spécifiées dans l'ABI C++ pour l'initialisation de la statique locale thread-safe. Vous pouvez utiliser cette option pour réduire légèrement la taille du code dans un code qui n'a pas besoin d'être thread-safe.

Jetez également un coup d'œil à l'ancien thread Les variables statiques d'une fonction sont-elles thread-safe dans GCC?

15
Denis Glotov