Статические локальные переменные инициализируются при первом вызове функции:
Переменные, объявленные в области блока со спецификатором static, имеют статический период хранения, но инициализируются, когда первый элемент управления проходит через их объявление (если их инициализация не является zero- или константной инициализацией, которая может быть выполнена до того, как блок будет введен первым). При всех последующих вызовах декларация пропущена.
Кроме того, в С++ 11 есть еще больше проверок:
Если несколько потоков пытаются инициализировать одну и ту же статическую локальную переменную одновременно, инициализация происходит ровно один раз (аналогичное поведение можно получить для произвольных функций с помощью std :: call_once). Примечание. В обычных реализациях этой функции используются варианты дважды проверенного шаблона блокировки, что уменьшает накладные расходы во время выполнения для уже инициализированной локальной статистики для одного неатомного логического сравнения. (поскольку С++ 11)
В то же время глобальные переменные, похоже, инициализируются при запуске программы (хотя технически только выделение/освобождение упоминается в cppreference):
статическая продолжительность хранения. Хранилище для объекта выделяется, когда программа начинается и освобождается, когда программа заканчивается. Существует только один экземпляр объекта. Все объекты, объявленные в области пространства имен (включая глобальное пространство имен), имеют такую продолжительность хранения, а также те, которые объявлены со статическими или внешними.
Так, например, следующий пример:
struct A {
// complex type...
};
const A& f()
{
static A local{};
return local;
}
A global{};
const A& g()
{
return global;
}
Правильно ли я предполагаю, что f()
должен проверить, была ли его переменная инициализирована каждый раз, когда она вызывается, и, следовательно, f()
будет медленнее, чем g()
?