TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.36K subscribers
Post #1072 4.58K
​​std::terminate. Когда вызывается
#опытным

Давайте посмотрим на список ситуаций, при которых вызывается std::terminate. Некоторые из них вполне мемные и заслуживают отдельных взвизгов, что так вообще можно в языке. Будем рассматривать более-менее понятные примеры, без малоизвестных динозавров. Погнали:

🔞 Вы бросили исключение, но не перехватили его нигде по стеку вызовов:
int main() {
throw 42; // нет catch → terminate
}


🔞 Исключение покидает noexcept функцию:
void foo() noexcept {
throw 42;
}

Частый вопрос на собесах: что будет если в деструкторе кинуть исключение? Тут без всяких раскруток стеков будет сразу terminate, потому что все деструкторы по умолчанию noexcept.

🔞 Деструктор бросает исключение во время раскрутки стека. Если вы уже такие смелые, что отменили noexcept спецификацию для деструкторов, то будьте готовы к аварийному завершению приложения. Если деструктор такого объекта вызовется во время раскрутки стека, ждите гитлер капут:
struct A {
~A() noexcept(false) { throw 1; }
};
int main() {
try {
A a;
throw 2;
} catch(...) {}
}


🔞 Из конструктора статического объекта вылетает исключение. В языке нет средств отловить такие исключения, поэтому сразу ломаемся:
struct A {
A() { throw 1; }
};
static A a;
int main() {}


🔞 В ту же песню залетает исключение из деструктора статических объектов. При нормальном завершении программы вызываются деструкторы глобальных объектов и если оттуда вылетит исключение, его никто не сможет поймать:

struct A {
~A() noexcept(false) { throw 1; }
};
static A a;
int main() {}


🔞 Из функции, зарегистрированной через atexit, вылетает исключение. Если вы хотите, чтобы при штатном завершении программы выполнилась функция, бросающая исключение, то у вас специфические вкусы. Такое исключение невозможно перехватить, поэтому тут же упадем:
void boom() { throw 1; }
int main() {
std::atexit(boom); // при выходе из main вызовется boom → terminate
}


🔞 Пустой throw без активного на данный момент исключения. Что вы хотели этим сказать - непонятно, зачем разрешать такое - тоже.
int main() {
throw; // нет текущего исключения → terminate
}


🔞 Из копирующего конструктора исключения вылетает исключение. Что-то такое:
struct MyExcept {
MyExcept() = default;
MyExcept(const MyExcept&) { throw 1; }
};

int main() {
try {
MyExcept e;
throw e;
} catch (MyExcept) {
}
}


Тут объект исключения после создания копируется во внутренний объект исключения, который будет переноситься механизмом раскрутки стека. Еще до раскрутки стека и вызова обработчика. В этом случае как бы произошла ошибка при выбросе исключения и это вполне аварийная ситуация, заканчивающаяся terminate. Ситуация странная, последствия вполне понятны.

🔞 Потоковая функция завершается исключением. Если исключение вылетает из последнего фрейма стека любого потока, вызывается std::terminate.
void thread_func() { throw 42; }

int main() {
std::thread t(thread_func);
t.join();
}

🔞 Вызвался деструктор или приваивание перемещением у joinable потока. Его не присоединили и не отсоединили и хотят уничтожить. А он уничтожил их:
int main() {
std::thread t([]{});
// деструктор t вызывается без join/detach → terminate
}


🔞 Вы мануально вызвали std::terminate. Хотите явно аварийно грохнуть программу и не плясать с бубнами, вам это дозволено:
int main() {
std::terminate();
}


Есть еще пару кейсов с потоковыми токенами остановки и с новой библиотекой std::execution, но это экзотика.

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

Terminate your enemies. Stay cool.
  • 👍 20
  • ❤ 13
  • 🔥 6
  • 👏 1
More from @grokaemcpp
  1. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  2. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  3. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  4. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  5. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
  6. Sep 25, 2026​​std::spanstream #опытным Радостная весть для всех, кто пользуется iostreams! В C++23 доб…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →