std::terminate în C++

Oprește imediat programul; este apelată automat când o excepție nu este prinsă nicăieri.

Sintaxă
#include <exception>
[[noreturn]] void terminate() noexcept;
std::terminate_handler set_terminate(std::terminate_handler f) noexcept;

Ce face std::terminate

std::terminate() încheie programul brusc, apelând std::abort: destructorii obiectelor locale nu mai rulează, fișierele pot rămâne nescrise complet. Codul de ieșire nu este 0, iar sistemul îl raportează ca oprire anormală.

De obicei nu o apelezi tu; o apelează limbajul când ceva nu mai poate fi reparat: o excepție care nu este prinsă de niciun catch, o excepție care iese dintr-o funcție noexcept, un std::thread distrus fără join/detach.

Cu std::set_terminate poți înregistra o funcție care rulează chiar înainte de oprire (de exemplu scrie un mesaj în jurnal). Funcția nu are voie să revină; trebuie să încheie programul. Exemplele de mai jos opresc programul, așa că rezultatul lor a fost copiat dintr-o rulare reală.

Ce returnează

Nu returnează niciodată.

Exemple

Exemplul 1: Excepție neprinsă

Nu există niciun catch, deci se apelează std::terminate. Mesajul este cel afișat de libc++ pe macOS; programul se oprește cu codul 134 (semnalul SIGABRT).

#include <print>
#include <stdexcept>

int main() {
    std::println("Pornesc...");
    throw std::runtime_error("Fișierul config.txt lipsește");
    std::println("Această linie nu se afișează");
}

Rezultat (programul se oprește cu eroare)

Pornesc...
libc++abi: terminating due to uncaught exception of type std::runtime_error: Fișierul config.txt lipsește

Exemplul 2: Un handler propriu cu set_terminate

Handlerul afișează un mesaj, apoi oprește programul cu std::abort, cum ar face și handlerul implicit.

#include <cstdlib>
#include <exception>
#include <print>

int main() {
    std::set_terminate([] {
        std::println(stderr, "Eroare fatală. Salvez jurnalul și închid.");
        std::abort();
    });

    std::println("Lucrez...");
    std::terminate();
}

Rezultat (programul se oprește cu eroare)

Lucrez...
Eroare fatală. Salvez jurnalul și închid.

Greșeli frecvente

  • Arunci o excepție dintr-un destructor sau dintr-o funcție noexcept. Excepția nu poate ieși de acolo, așa că programul se oprește cu std::terminate, fără ca vreun catch să o vadă.
  • Folosești std::terminate pentru erori obișnuite. Nu se face nicio curățenie; aruncă o excepție sau ieși din main cu un cod de eroare.

Comenzi înrudite

  • std::exception: Clasa de bază a tuturor excepțiilor din biblioteca standard; what() returnează mesajul erorii.
  • noexcept: Marchează o funcție care promite că nu aruncă excepții; ca operator, verifică la compilare dacă o expresie poate arunca.
  • std::thread: Pornește o funcție pe un fir de execuție separat, care rulează în paralel cu restul programului.
  • assert: Verifică o condiție care trebuie să fie mereu adevărată; dacă e falsă, oprește programul cu un mesaj.
  • std::unreachable: Îi spune compilatorului că un punct din cod nu poate fi atins niciodată, ca să optimizeze.