mslomp
(usa Slackware)
Enviado em 28/04/2009 - 21:28h
segue um exemplo básico, onde o objetivo é apenas dividir um número por outro, este fornecido como argumento. coloquei os números das linhas para facilitar o entendimento:
01 #include <stdio.h>
02 #include <setjmp.h>
03
04 /* exceções */
05 #define DIV_BY_ZERO 1 /* divisão por zero */
06 #define NO_ARG_SPEC 2 /* nenhum argumento especificado */
07
08 int
09 main(int argc, char** argv) {
10 jmp_buf jmp;
11 switch(setjmp(jmp)){
12 case 0:
13 if(argc>1) {
14 int i = atoi(argv[1]);
15 if(i==0)
16 longjmp(jmp,DIV_BY_ZERO );
17 int x = 10 / i;
18 printf("Resultado: %d\n",x);
19 }
20 else {
21 longjmp(jmp,NO_ARG_SPEC);
22 }
23 break;
24 case DIV_BY_ZERO:
25 printf("Argumento invalido... divisao por zero!\n");
26 break;
27 case NO_ARG_SPEC:
28 printf("Argumento nao especificado!\n");
29 break;
30 }
31 return 0;
32 }
traduzindo em miúdos: digamos que você defina duas exceções: divisão por zero e falta de argumento (linhas 05 e 06). o programa começa definindo uma variável do tipo jmp_buf (10), que armazena o índice do contexto a ser salvo por setjmp. na linha 11, setjmp irá salvar o contexto e será avaliado por switch. como jmp é zero na primeira avaliação, cairemos no caso 0 (12). supondo que algum argumento (numérico) tenha sido passado ao programa, avaliaremos se o valor é zero (15). caso afirmativo, teríamos na linha 17 uma divisão por zero, o que não queremos. iremos então 'disparar uma exceção' (DIV_BY_ZERO) através de longjmp, que fará com que o contexto retorne ao local salvo anteriormente (linha 11), tendo jmp como o valor correspondente à exceção. switch então irá saltar para o caso DIV_BY_ZERO. supondo que nenhum argumento tenha sido passado, o que foi avaliado em 13, iremos à linha 21 onde, seguindo o mesmo raciocínio, dispararemos a exceção NO_ARG_SPEC.
agora podemos juntar tudo isso e construir as macros try, throw e catch e aplicá-los no exemplo acima:
#include <stdio.h>
#include <setjmp.h>
#define try jmp_buf jmp; switch(setjmp(jmp)){case 0:
#define throw(e) longjmp(jmp,e)
#define catch(e) break;case e:
/* exceções */
#define DIV_BY_ZERO 1 /* divisão por zero */
#define NO_ARG_SPEC 2 /* nenhum argumento especificado */
int
main(int argc, char** argv) {
try {
if(argc>1) {
int i = atoi(argv[1]);
if(i==0)
throw(DIV_BY_ZERO);
int x = 10 / i;
printf("Resultado: %d\n",x);
}
else
throw(NO_ARG_SPEC);
}
catch(DIV_BY_ZERO) {
printf("Argumento invalido... divisao por zero!\n");
}
catch(NO_ARG_SPEC) {
printf("Argumento nao especificado!\n");
}
}
return 0;
}