Когда инициализируются данные анонимного пространства имен? - PullRequest
4 голосов
/ 01 декабря 2008

Я использовал анонимные пространства имен для хранения локальных данных и функций и хотел знать, когда данные инициализируются? Это когда приложение запускается так же, как статические данные, или это зависит от компилятора? Например:

// foo.cpp
#include "foo.h"

namespace {

const int SOME_VALUE = 42;

}

void foo::SomeFunc(int n)
{
    if (n == SOME_VALUE)
    {
        ...
    }
}

Возникает вопрос о том, чтобы сделать какой-то код потокобезопасным. В приведенном выше примере мне нужно быть уверенным, что SOME_VALUE инициализируется перед первым вызовом SomeFunc.

Ответы [ 4 ]

6 голосов
/ 01 декабря 2008

C ++ Standard, 3.6.2 / 1 :

Обнуление инициализации и инициализация с константой выражение в совокупности называется статическая инициализация; все остальные инициализация динамическая инициализация. Объекты типов POD (3.9) со статической продолжительностью хранения инициализируется с помощью константных выражений (5.19) инициализируется до происходит динамическая инициализация. Объекты со статической продолжительностью хранения определяется в области имен пространства в том же блок перевода и динамически инициализируется должен быть инициализирован в порядок, в котором их определение появляется в блоке перевода.

Это фактически означает, что даже когда другая единица перевода вызывает вашу функцию SomeFunc извне, ваша константа SOME_VALUE всегда будет правильно инициализирована, поскольку она инициализируется с помощью константного выражения .

Единственный способ для вашей функции вызываться раньше (до main) - это при инициализации объекта с динамической инициализацией. Но к тому времени, согласно стандартной цитате, инициализация вашей переменной POD уже завершена.

2 голосов
/ 01 декабря 2008

В этом конкретном случае (глобальная переменная const) переменная "инициализируется" во время компиляции.

SOME_VALUE всегда равно 42.

Фактически, большинство (все?) Компиляторов на самом деле скомпилируют это так, как если бы оно было жестко закодировано:

void foo::SomeFunc(int n)
{
    if (n == 42)
    {
        ...
    }
}
1 голос
/ 01 декабря 2008

Пространства имен не имеют никакого отношения ко времени инициализации. Все, что делает пространство имен, это изменяет имена, которые ему принадлежат.

0 голосов
/ 01 декабря 2008

Правильный ответ на актуальный вопрос вы найдете в ответе Матье.

Однако обратите внимание, что анонимное пространство имен не влияет на начало и конец времени жизни глобальных и / или статических объектов. Другими словами, вы так же уязвимы для статического порядка инициализации проблем, как и при использовании простых старых глобалов.

Ссылка также содержит несколько советов по предотвращению проблемы, используя "конструкцию при первом использовании", в следующей теме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...