Em linguagens de programação de alto nível tais como C++, Python e Java, há o recurso de tratamento de exceções, que permite que programadores escrevam blocos try - catch e funções/métodos que disparem exceções.
Com uso de tais recursos, o fluxo de lógica do programa fica no bloco try, separado do tratamento das exceções, que ficam no bloco catch. O uso primário do tratamento de exceções é separar o fluxo da lógica do fluxo de tratamento de erros (nesse caso usa-se exceções para identificar os erros). Dentro dessa abordagem, as exceções são usadas para indicar erros que ocorrem. Tratamento de exceções, atualmente, é uma técnica desejável em muitos ambiente de desenvolvimento.
Programadores de C, geralmente utilizam o valor de retorno da função para indicar algum erro, como ocorre nas funções de alocação dinâmica, por exemplo. Essa abordagem é adequada a proposta da linguagem de ser uma linguagem de médio nível eficiente, porém nem sempre é adequada ao desenvolvimento do software. Em uma função onde todo valor de retorno é válido, essa abordagem mostra-se ineficaz, e a elegância do código seria ameaçada para resolver tal problema, como mostra o exemplo.
int divide1(int a, int b, int *ok)
{
if (b) {
if (ok)
*ok = 1;
return a / b;
} else {
if (ok)
ok = 0;
return 0;
}
}
struct ret
{
int ok;
int value;
};
struct ret divide2(int a, int b)
{
struct ret res = {1, 0};
if (b)
res.value = a / b;
else
res.ok = 0;
return res;
}
int main()
{
int i;
{
int ok;
// A and B should be defined as macros
int unsafe_value = divide1(A, B, &ok);
if (ok)
i = unsafe_value;
}
{
struct ret tmp = divide2(A, B);
if (tmp.ok)
i = tmp.value;
}
return 0;
}
Uma prática que vem substituindo com sucesso o uso de valores de retorno para a indicação de erros é o uso de exceções. Essa prática traz vários benefícios, principalmente relacionados com a legibilidade e manutenção do código.
Neste texto, serão demonstradas as funcionalidades requeridas para que o tratamento de exceções seja aplicado e será feita a apresentação de uma implementação na linguagem de programação C, que é uma das linguagens de médio nível mais populares. Por ser uma linguagem de médio nível, adotar tratamento de exceções como parte do padrão que define a linguagem pode não ser adequado, pois o código-fonte iria esconder certos comportamentos, que não é característico em uma linguagem de médio nível.
Assim sendo, este artigo tem por objetivo:
i) apresentar técnicas que imitem o tratamento de exceções que expõem a implementação proposta;
ii) descrever facilidades implementadas através de macros que viabilizam seu uso e;
iii) avaliar o desempenho.
Nesse texto foi adotada uma abordagem incremental, onde há uma definição simples do tratamento de exceções no início, e a cada seção teremos uma definição mais próxima da utilizada na programação no mundo real.