Время жизни функции static
переменные начинаются в первый раз <глоток> [0] глоток>, процесс выполнения программы встречается с объявлением, и это заканчивается при завершении программы. Это означает, что время выполнения должно выполнить некоторую бухгалтерию для разрушения его, только если это было на самом деле создано.
Кроме того, так как в стандарте говорится, что деструкторы статических объектов должны работать в обратном порядке завершения их конструкции <глоток> [1] глоток>, и порядок конструкции может зависеть от определенного прогона программы, порядок конструкции должен быть принят во внимание.
Пример
struct emitter {
string str;
emitter(const string& s) : str(s) { cout << "Created " << str << endl; }
~emitter() { cout << "Destroyed " << str << endl; }
};
void foo(bool skip_first)
{
if (!skip_first)
static emitter a("in if");
static emitter b("in foo");
}
int main(int argc, char*[])
{
foo(argc != 2);
if (argc == 3)
foo(false);
}
Вывод:
C:>sample.exe
Созданный в нечто
Уничтоженный в нечтоC:>sample.exe 1
Созданный, в если
Созданный в нечто
Уничтоженный в нечто
Уничтоженный, в еслиC:>sample.exe 1 2
Созданный в нечто
Созданный, в если
Уничтоженный в том, если
Уничтоженный в нечто
[0]
С тех пор C++ 98 <глоток> [2] глоток> не имеет никакой ссылки на несколько потоков, как это будет, ведет себя в многопоточной среде, является неуказанным, и может быть проблематичным как упоминания Roddy.
[1]
C++ 98 раздел 3.6.3.1
[basic.start.term]
[2]
В C++ 11 помех инициализируются ориентированным на многопотоковое исполнение способом, это также известно как Волшебная Статика .
Motti прав относительно порядка, но существуют некоторые другие вещи рассмотреть:
Компиляторы обычно используют скрытую переменную флага, чтобы указать, были ли локальные помехи уже инициализированы, и этот флаг проверяется на каждой записи в функцию. Очевидно, это - маленький хит производительности, но что является большим количеством беспокойства, то, что этот флаг, как гарантируют, не будет ориентирован на многопотоковое исполнение.
, Если у Вас есть локальные помехи как выше, и foo
, назван от нескольких потоков, у Вас могут быть условия состязания, вызывающие plonk
, чтобы быть инициализированными неправильно или даже многократно. Кроме того, в этом случае plonk
может быть разрушен различным потоком, чем тот, который создал его.
Несмотря на то, что говорит стандарт, я очень опасался бы фактического порядка локального статического разрушения, потому что возможно, что можно невольно полагаться на статическое существо, все еще допустимое после того, как это было разрушено, и это действительно трудно разыскать.
FWIW, Разработчик C++ Codegear не разрушает в ожидаемом порядке согласно стандарту.
C:\> sample.exe 1 2
Created in foo
Created in if
Destroyed in foo
Destroyed in if
..., который является другой причиной не полагаться на порядок разрушения!