1

Здесь сказано, что статические локальные переменные не инициализируются, если инициализация выбрасывает исключение:

If the initialization throws an exception, the variable is not considered to be initialized, and initialization will be attempted again the next time control passes through the declaration.

Далее сказано, что деструктор таких переменных вызывается только в случае их успешной инициализации:

The destructor for a block-scope static variable is called at program exit, but only if the initialization took place successfully.

Правильно ли я понимаю, что если инициализация локальных статических переменных выбрасывает исключение для всех попыток инициализации, то память в начале старта программы для них будет выделена (т.к. они имеют статическое время жизни), однако освобождена не будет (т.к. деструктор не вызывается)?

  • 2
    Статические переменные располагаются как правило в сегменте BSS. Память для них резервируется в момент старта программы (процесса) один раз до отработки статического конструктора, а освобождается в момент прекращения существования процесса, а не после отработки статического деструктора. – nick_n_a Nov 07 '19 at 07:15
  • @nick_n_a разве деструктор не должен быть вызван до освобождения памяти? – cppforlife Nov 07 '19 at 07:19
  • Есть разница между (динамическим) деструктором, и статическим деструктором. Статический деструктор ведет себя так как написано в описании. Компилятор делает разные вызовы (действия) на разные виды деструкторов. – nick_n_a Nov 07 '19 at 07:22
  • 1
    разве деструктор не должен быть вызван до освобождения памяти - а я не говорил обратного. Он будет вызан до освобождения (при условии описаном). – nick_n_a Nov 07 '19 at 07:40
  • если инициализация локальных статических переменных выбрасывает исключение для всех попыток инициализации, то обьект не будет создан, и говорить об освобождении памяти не приходится – AR Hovsepyan Nov 07 '19 at 07:47
  • @ARHovsepyan думаю, что создан (выделена память) он будет в начале программы в любом случае, а вот проинициализирован не будет – cppforlife Nov 07 '19 at 07:49
  • @cppforlife, ну хорошо, посмотрим это на примере. – AR Hovsepyan Nov 07 '19 at 07:53

2 Answers2

1

Деструктор не освобождает память, поэтому всё освободится и без него в конце программы. Подробнее про это написано здесь https://ru.stackoverflow.com/a/590529/358371

rulp
  • 21
0

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

struct A {
    static int count;
    int n;
    A(const int k) : n(k) 
    { std::cout << "construct A" << ++count << std::endl; }
};
int A::count;
 int func(const int n) {
     if (n < 0)
         throw "error";
}

int main() {

    try {
        static A a1{ func(3) };
        static A a2{ func(-3) };
    }
    catch (const char* s)
    {
        std::cout << s;
    }
    return 0;
}
AR Hovsepyan
  • 15,934