Em C++, lidar corretamente com erros é essencial para garantir a estabilidade e previsibilidade de um programa.
Dois mecanismos comuns usados para esse fim são std::runtime_error
, que faz parte do sistema de exceções da linguagem, e std::exit
, que encerra o processo imediatamente.
Embora ambos possam ser usados para sinalizar falhas, eles possuem propósitos completamente diferentes: um foca no tratamento e recuperação, o outro na finalização imediata.
Nesse artigo vamos ver o funcionamento de cada um, mostrar quando aplicá-los e discutir qual abordagem é mais adequada em diferentes contextos de desenvolvimento.
std::runtime_error
std::runtime_error
é uma exceção da biblioteca padrão C++ derivada de std::exception
.
Serve para sinalizar erros em tempo de execução que impedem a continuação normal do programa.
Uso:
#include <stdexcept>
#include <iostream>
void carregarArquivo(const std::string& caminho) {
if (caminho.empty()) {
throw std::runtime_error("Caminho do arquivo inválido");
}
// ...
}
int main() {
try {
carregarArquivo("");
} catch (const std::runtime_error& e) {
std::cerr << "Erro: " << e.what() << '\n';
}
}
Características:
- É lançada com
throw
e tratada comtry/catch
. - Permite propagação controlada do erro, preservando o estado do programa.
- Garante liberação automática de recursos via stack unwinding (destrutores de objetos locais são chamados).
- Ideal para erros recuperáveis ou previsíveis, como falha de leitura, valor inválido, etc.
std::exit
std::exit
(definido em <cstdlib>
) termina o programa imediatamente, retornando um código de status ao sistema operacional.
Uso:
#include <cstdlib>
#include <iostream>
int main() {
std::cerr << "Erro fatal, encerrando.\n";
std::exit(EXIT_FAILURE);
}
Características:
- Não lança exceção, nem faz stack unwinding.
- Objetos automáticos (locais) não têm seus destrutores chamados.
- Objetos estáticos e globais ainda são destruídos.
- Ideal para erros fatais ou situações onde o estado do programa está completamente corrompido.
Qual usar e quando?
Situação | Recomendado | Motivo |
---|---|---|
Erro previsível ou recuperável | std::runtime_error |
Permite tratamento via try/catch e limpeza automática |
Erro irrecuperável (ex: corrupção de memória, falha grave de inicialização) | std::exit |
Finaliza de forma imediata e controlada |
Código de biblioteca ou engine | std::runtime_error |
Dá ao chamador a chance de reagir |
Programa pequeno ou utilitário simples | std::exit |
Simplicidade, sem necessidade de exceções |
- Use
std::runtime_error
quando quiser propagar e tratar erros dentro da lógica do programa. - Use
std::exit
apenas quando não há como continuar — o erro é fatal. - Em geral,
std::runtime_error
é mais seguro e flexível, pois mantém o controle de fluxo e garante destruição adequada de recursos.
Dependendo do contexto.
throw std::runtime_error(...)
Melhor na maioria dos casos.
- Permite tratamento com
try/catch
, stack unwinding, e destrutores são chamados corretamente (RAII). - Usado quando há um erro lógico ou de fluxo, e você quer propagar o erro.
throw std::runtime_error("Arquivo inválido");
std::exit(1)
Use só se quiser encerrar IMEDIATAMENTE e não precisa liberar recursos.
- Não faz stack unwinding → destrutores não são chamados.
- Bom para nível
main()
, ferramentas, ou se realmente precisa abortar sem exceções.
std::cerr << "Erro fatal\n";
std::exit(1);
Situação | Melhor opção |
---|---|
Código com RAII/recursos alocados | throw std::runtime_error |
Em main() ou ferramenta simples |
std::exit(1) |
Precisa de tratamento de erro | throw |
Quer encerrar seco e rápido | std::exit(1) |
Recomendação padrão moderna: use throw
, não exit
, a menos que tenha motivo real.
Top comments (0)