Newsgroup: it.comp.lang.c++
Titolo: try e catch su errori matematici

Per intercettare i vari division by zero (integer, double, ecc.) e overflow
come vanno utilizzati i vari try, catch ?
try {
    int a = 10;
    int b = 0;
    int c = a / b;
}
catch ( /* COSA DEVO SCRIVERE QUI */) {
}

...

Non c'è un'eccezione standard per la divisione per 0.
Il mio compilatore restituisce come valore "inf" (infinito).
La cosa migliore da fare è evitare la divisione nel caso il divisore sia 0,
cioè
class ZeroDivision { };
try {
   int a=10;
   int b=0;
   if(b==0) throw ZeroDivision();
   int c=a/b;
}
catch(ZeroDivision) { /*fai quello che ti pare*/ }
Ovviamente in questo caso l'eccezione verrà sempre lanciata, ma è solo un
esempio.
Ciao
Domenico Barra

 }
Se non t'interessa sapere quale eccezione è stata generata ti basta
catch(...) { } che le prende tutte.
Cristiano


Gli errori di questo tipo (asincroni) non sono gestiti
tramite le eccezioni.
Invece di solito tali errori sono segnalati tramite i 'segnali'.
Non so se sia Standard ma ad esempio con il BCC 5.5
il segnale SIGFPE è usato per:
  Bad floating-point operation
  Arithmetic error caused by
  division by 0, invalid operation, etc.
In questo caso quello che si può fare è installare un handler
per questo segnale e fargli lanciare una eccezione.
#include <csignal>
struct zero_divide {  };
void handler(int)
{
    // reinstalla l'handler
    std::signal(SIGFPE, handler);
    throw zero_divide();
}
#include <iostream>
int main()
{
    std::signal(SIGFPE, handler);
    try
    {
        float a = 10;
        float b = 0;
        float c = a / b;
    }
    catch(zero_divide&)
    {
        std::cerr << "divisione per zero\n";
    }
}
Così come con il BCC 5.5 funziona.
Manlio Perillo


Se nel try{} esegui solo operazioni matematiche puoi provare a mettere
(...)
Luc.

Lo standard non prevede che la divisione per 0 generi un'eccezione. Per
i numeri float credo siano seguite le convenzioni IEEE, che non conosco
ma che presumo richiedano venga restituito +/- infinito, per i tipi
interi dipende dal sistema, ma e' probabile che il programma abortisca.
Ad esempio sotto Windows la divisione per zero tra interi non e'
intercettabile con "catch" ne da BCB4 ne da gcc 2.95.2
Ciao,
Nicola

 cioè
Il problema e` pero' che ci sono anche problemi di overflow e capita spesso
che discutere formule molto complesso e` praticamente impossibile.
Mi serve proprio un metodo che possa intercettare qualsiasi tipo di errore
matematico anche non previsto.

> Invece di solito tali errori sono segnalati tramite i 'segnali'.
Grazie per la dritta. Ho trovato documentazione riguardante i segnali anche
per il Visual c++ e provero' a vedere cosa capita. Purtroppo sviluppo
applicazioni con MFC e ho la brutta sensazione che non funzioni.

 ha scritto nel
messaggio news:8u8v0s$1ha$2...@serv1.iunet.it...

Se usi MFC non dovrebbe cambiare niente.
Comunque per gli interi la divisione per zero non genera segnali
(o forse un segnale diverso di SIGFPE).
Come avrai notato ho usato i float.
Purtroppo la documentazione in linea della Borland non è
molto dettagliata.
Ricordati comunque che per maggiori informazioni puoi rivolgerti
ai newsgroup propri del compilatore che usi.
Manlio Perillo

matematico anche non previsto.
Sono ben lieto (si fa per dire) di risponderti che lo Standard non prevede
alcunché del genere: devi implemetare da solo la strategia che piů ti
conviene.
Domenico Barra

 intercettabile con "catch" ne da BCB4 ne da gcc 2.95.2
Il VC++ la intercetta.
Windows supporta come sistema operativo la gestione di alcune eccezioni
hardware (quella che viene chiamata SEH), tra cui quella della divisione
per 0 tra interi.
Ad esempio:
#include <windows.h>
int main()
{
    __try {
    int a = 10;
    int b = 0;
    int c = a / b;
    }
     __except (EXCEPTION_EXECUTE_HANDLER)   {
           return 1;
   }
     return 0;
}
Ci sono tre cose da dire:
1) La Microsoft stessa sconsiglia di usare la SEH, e dice invece di usare
le eccezzioni del C++ standard
2) La cosa non è portabile su altri sistemi operativi
3) La sintassi __try ... __except è un estensione della Microsoft al C
standard, e quindi non è detto che sia supportata da altri compilatori per
Windows.
Una cosa mi ha stupito, nel MSDN c'è scritto:
"If the exception-declaration statement is an ellipsis (...), the catch
clause handles any type of exception, including C exceptions as well as
system-generated and application-generated exceptions. This includes
exceptions such as memory protection, divide-by-zero, and floating-point
violations. An ellipsis catch handler must be the last handler for its try
block."
Di solito quando il compilatore si comporta in maniera non standard c'è un
bel "Microsoft Specific —>" ad indicarlo. Siccome qui non c'è, pensavo che
fosse una cosa portabile. Ci sono rimasto male.
Fulvio.

block."
Io ve lo avevo detto... 8PPP
Luc.

 conviene.
Evviva!
Chissa` perche` noi poveri programmatori cad/cam siamo sempre posti nel
fanalino di coda?