Eu tendo a adicionar muitas asserções ao meu código C ++ para tornar a depuração mais fácil sem afetar o desempenho das compilações. Agora,assert
é uma macro C pura projetada sem mecanismos C ++ em mente.
Por outro lado std::logic_error
, C ++ define , que deve ser lançado nos casos em que há um erro na lógica do programa (daí o nome). Lançar uma instância pode ser a alternativa perfeita e mais C ++ para assert
.
O problema é que assert
e abort
ambos terminam o programa imediatamente sem chamar destruidores, portanto, ignorando a limpeza, enquanto lançar uma exceção manualmente adiciona custos de tempo de execução desnecessários. Uma maneira de contornar isso seria criar uma macro de asserção própria SAFE_ASSERT
, que funciona exatamente como a contraparte C, mas lança uma exceção em caso de falha.
Posso pensar em três opiniões sobre este problema:
- Atenha-se à afirmação de C. Como o programa é encerrado imediatamente, não importa se as alterações foram desenroladas corretamente. Além disso, usar
#define
s em C ++ é tão ruim quanto. - Lance uma exceção e capture-a em main () . Permitir que o código ignore destruidores em qualquer estado do programa é uma prática ruim e deve ser evitado a todo custo, assim como as chamadas para terminate (). Se exceções são lançadas, elas devem ser capturadas.
- Lance uma exceção e deixe-o encerrar o programa. Uma exceção ao encerrar um programa está bem e, devido a
NDEBUG
, isso nunca acontecerá em uma versão de construção. A captura é desnecessária e expõe detalhes de implementação do código interno amain()
.
Existe uma resposta definitiva para este problema? Alguma referência profissional?
Editado: Ignorar destruidores, obviamente, não é um comportamento indefinido.
static_assert
onde for apropriado, se tiver disponível.
std::bug
?
std::abort()
; ele apenas levantará um sinal que fará com que o processo seja encerrado.
logic_error
é o erro lógico. Um erro na lógica do programa é chamado de bug. Você não resolve bugs lançando exceções.