Floating point exceptions



  • Hallo C Forum!
    Trotz der Suche nach Beispielen komme ich auf keine gute Lösung bei meinem Problem: In einem mittlerweile relativ großen Programm würde ich gerne die Funktionen aus fenv.h nutzen. Dazu habe ich folgende Funktion geschrieben:

    void fp_error(const char *file, int line, const char *fname)
    {
    int set_excepts=fetestexcept(FE_ALL_EXCEPT);
    if(set_excepts&FE_DIVBYZERO) error_msg("there was a division by zero",file,line,fname);
    if(set_excepts&FE_INEXACT) error_msg("sometimes double is not enough",__FILE__,__LINE__,__func__);
    if(set_excepts&FE_INVALID) error_msg("there was an invalid operation",__FILE__,__LINE__,__func__);
    if(set_excepts&FE_OVERFLOW) error_msg("overflow fp error",__FILE__,__LINE__,__func__);
    if(set_excepts&FE_UNDERFLOW) error_msg("underflow fp error",__FILE__,__LINE__,__func__);
    
    feclearexcept(FE_ALL_EXCEPT);
    }
    

    Jetzt kann ich natürlich diese Funktion in jeden beliebigen Teil meines Programms einfügen. Was ich aber gerne hätte: Eine Art Signal Behandlung, d.h. sobald eines der aufgeführten Ereignisse in "fetestexcept(FE_ALL_EXCEPT)" zutrifft, hält das Programm bzw. gibt ein Signal. In diesem Zusammenhang weiß ich leider auch nicht recht, ob das überhaupt möglich ist...
    Es gibt hier

    http://www.cplusplus.com/reference/clibrary/csignal/signal/

    das macro SIGFPE, allerdings glaube ich nicht, dass alle Ausnahmen, wie z.B. "FE_INEXACT" (auf die ich besonders aus bin) auch detektiert werden...

    Vielen Dank für Tipps
    Clemens



  • error_msg ist eine eigene Funktion, klar, aber

    if(set_excepts&FE_DIVBYZERO) error_msg("there was a division by zero",file,line,fname);
    if(set_excepts&FE_INEXACT) error_msg("sometimes double is not enough",__FILE__,__LINE__,__func__);
    if(set_excepts&FE_INVALID) error_msg("there was an invalid operation",__FILE__,__LINE__,__func__);
    if(set_excepts&FE_OVERFLOW) error_msg("overflow fp error",__FILE__,__LINE__,__func__);
    if(set_excepts&FE_UNDERFLOW) error_msg("underflow fp error",__FILE__,__LINE__,__func__);
    

    bei den letzten 4 Aufrufen soll das Argument dieser error_msg natürlich immer ",file,line,fname" lauten 😉



  • Deine beschriebenen Zustände werden alle von C99 unterstützt, also ganz normal mit der C89-Funktion signal arbeiten:

    ...
    signal( SIGFPE , handler );
    ...
    

    Der Haken liegt aber in den auf vielen Systemen explizit einzuschaltenden Floating-Point-Exceptions, dafür gibt es leider keine Standardfunktion, das ist Compiler/Maschinen-abhängig.



  • Vielen Dank. Ich verstehe nur nicht, wie ich mir anzeigen lassen kann, welcher der exceptions vorliegt. Meine genannte Funktion kann ich nicht nutzen, da die signal Funktion einen handler von der Art

    handler(int i)
    

    benötigt!?! Mit der signal Funktion habe ich noch nie gearbeitet und verstehe die Implementierung auch nicht ganz. Wäre sowas richtig:

    int main(void)
    {
    void (*prev_fn)(int);
    prev_fn = signal(SIGFPE,handler);
    if (prev_fn==SIG_IGN) signal(SIGFPE,SIG_IGN);
    
    /* das programm */
    }
    

    Das habe ich so von http://www.cplusplus.com/reference/clibrary/csignal/signal/ "kopiert". Die Zeile " prev_fn=... " sorgt dafür, dass der handler aufgerufen wird, sobald das Makro SIGFPE auftritt? Die nächste Zeile erschließt sich mir nicht. Wenn der Rückgabewert von signal() gleich SIG_IGN ist, wird der handler mit SIG_IGN überschrieben?


Anmelden zum Antworten