Kann ich gcc dazu bringen, mir mitzuteilen, wenn eine Berechnung zur Laufzeit NaN oder inf ergibt?

Lesezeit: 2 Minuten

Benutzer-Avatar
Jordan Lewis

Gibt es eine Möglichkeit, gcc anzuweisen, ein SIGFPE oder ähnliches als Antwort auf eine resultierende Berechnung auszulösen NaN oder (-)inf zur Laufzeit, wie bei einer Division durch Null?

Ich habe die ausprobiert -fsignaling-nans Flagge, was nicht zu helfen scheint.

  • -fsignaling-nans ist die Laufzeit, nicht die Kompilierzeit.

    – LiraNuna

    31. Mai 2010 um 6:09 Uhr

Benutzer-Avatar
Markus Dickinson

Nahezu jede Gleitkommaoperation oder mathematische Bibliotheksfunktion, die eine NaN aus Nicht-NaN-Eingaben erzeugt, sollte auch die Gleitkommaausnahme „ungültige Operation“ signalisieren. In ähnlicher Weise signalisiert eine Berechnung, die aus endlichen Eingaben eine Unendlichkeit erzeugt, normalerweise entweder die Gleitkommaausnahme “Teilen durch Null” oder “Überlauf”. Sie möchten also eine Möglichkeit, diese Ausnahmen in ein SIGFPE umzuwandeln.

Ich vermute, dass die Antwort stark systemabhängig sein wird, da die Steuerung von Gleitkomma-Traps und -Flags wahrscheinlich eher von der Plattform-C-Bibliothek als von gcc selbst bereitgestellt wird. Aber hier ist ein Beispiel, das für mich unter Linux funktioniert. Es verwendet die feenableexcept Funktion ab fenv.h. Das _GNU_SOURCE define ist notwendig, damit diese Funktion deklariert werden kann.

#define _GNU_SOURCE
#include <fenv.h>

int main(void) {
    double x, y, z;
    feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);

    x = 1e300;
    y = 1e300;
    z = x * y; /* should cause an FPE */

    return 0;
}

Eine Einschränkung: Ich denke, dass es bei einigen Setups möglich ist, dass die Ausnahme erst dann tatsächlich generiert wird nächste Gleitkommaoperation nach derjenigen, die (theoretisch) sie hätte verursachen sollen, sodass Sie manchmal eine No-Op-Gleitkommaoperation (z. B. Multiplizieren mit 1,0) benötigen, um die Ausnahme auszulösen.

Benutzer-Avatar
Legenden2k

Auf MinGW 4.8.1 (GCC für Win32) sehe ich, dass die feenableexcept ist nicht definiert. Die Problemumgehung besteht darin, die Win32-Plattform zu verwenden _controlfp daher:

#undef __STRICT_ANSI__ // _controlfp is a non-standard function documented in MSDN
#include <float.h>
#include <stdio.h>

int main()
{
   _clearfp();
   unsigned unused_current_word = 0;
   // clearing the bits unmasks (throws) the exception
   _controlfp_s(&unused_current_word, 0, _EM_OVERFLOW | _EM_ZERODIVIDE);  // _controlfp_s is the secure version of _controlfp

   float num = 1.0f, den = 0.0f;
   float quo = num / den;
   printf("%.8f\n", quo);    // the control should never reach here, due to the exception thrown above
}

  • Dies scheint auf MinGW 4.6.2 nicht zu funktionieren (‘_clearfp()’ wurde in diesem Bereich nicht deklariert)

    – Antonello

    3. November 2015 um 15:15 Uhr

1205240cookie-checkKann ich gcc dazu bringen, mir mitzuteilen, wenn eine Berechnung zur Laufzeit NaN oder inf ergibt?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy