2008-12-01 3 views
4

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

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

namespace { 

const int SOME_VALUE = 42; 

} 

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

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

ответ

6

Стандартный C++ 3.6.2/1:

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

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

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

2

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

some_value всегда равна 42.

В самом деле, большинство (? Все) компилятор будет компилировать это как если бы он был жёстко:

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

Для правильного ответа на ваш фактический вопрос см Ответ Матье.

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

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

1

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

Смежные вопросы