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 hierhttp://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 MakroSIGFPE
auftritt? Die nächste Zeile erschließt sich mir nicht. Wenn der Rückgabewert vonsignal()
gleichSIG_IGN
ist, wird der handler mitSIG_IGN
überschrieben?