Mingw-64 Detect domain and range errors in math functions

Using C++11:

I am trying to determine how to handle domain and range errors using the g++ compiler (Mingw64). I have provided some sample code below which is the approach that I use for g++ on Linux systems. When I compile I get the following messages:

warning: ignoring #pragma STDC FENV_ACCESS [-Wunknown-pragmas] #pragma STDC FENV_ACCESS ON
error: 'math_errhandling' was not declared in this scope
error: 'MATH_ERRNO' was not declared in this scope
error: 'MATH_ERREXCEPT' was not declared in this scope

I have looked for these symbols in the normal include headers but I don't see them.  Any help is greatly appreciated. I must note that  math_errhandling, MATH_ERRNO,  MATH_ERREXCEPT and the pragma  STDC FENV_ACCESS are part of the c++(2011) standard.

#include <cmath>
#include <fenv>
#include <cerrno>


#pragma STDC FENV_ACCESS ON
if (math_errhandling & MATH_ERREXCEPT) {
feclearexcept(FE_ALL_EXCEPT);
}
errno = 0;
result = pow(x, y);

if ((math_errhandling & MATH_ERRNO) && errno != 0) {
  /* Handle range error */
}
else if ((math_errhandling & MATH_ERREXCEPT) &&
           fetestexcept(FE_INVALID | FE_DIVBYZERO |
                        FE_OVERFLOW | FE_UNDERFLOW) != 0) {
  /* Handle range error */
}
}
/ Use result... /
}
orondo jonesAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sarabandeCommented:
I have looked for these symbols in the normal include headers but I don't see them.
you have to look in your linux system where those expressions are coming from.

i have doubts that those non-standard expressions are portable to mingw. so i would try to comment all those things that don't compile or replace them by own functions (based on c++ standard modules only) if you think you would need them.

for example

if ((math_errhandling & MATH_ERRNO) && errno != 0) 

Open in new window


might be replaced by

if (errno != 0) 

Open in new window


probably without disadvantages because it was defeatable in the linux code as well.

Sara
0
orondo jonesAuthor Commented:
Actually, the expressions are part of the 2011 c++ standard.
0
phoffric\Commented:
I get thousands of hits when searching on the OP's keywords.

I see that you are using
#include <fenv>
I am not sure where you got that header file. For pure C++11, you should be using
#include <cfenv>

I have also seen <fenv.h> online.



Try running the code in this link
http://en.cppreference.com/w/cpp/numeric/math/math_errhandling
Make sure you include the compiler option to use C++11:
g++ -std=c++11

#include <iostream>
#include <cfenv>
#include <cmath>
#include <cerrno>
#include <cstring>
#pragma STDC FENV_ACCESS ON
int main()
{
    std::cout << "MATH_ERRNO is "
              << (math_errhandling & MATH_ERRNO ? "set" : "not set") << '\n'
              << "MATH_ERREXCEPT is "
              << (math_errhandling & MATH_ERREXCEPT ? "set" : "not set") << '\n';
    std::feclearexcept(FE_ALL_EXCEPT);
    errno = 0;
    std::cout <<  "log(0) = " << std::log(0) << '\n';
    if(errno == ERANGE)
            std::cout << "errno = ERANGE (" << std::strerror(errno) << ")\n";
    if(std::fetestexcept(FE_DIVBYZERO))
        std::cout << "FE_DIVBYZERO (pole error) reported\n";
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
orondo jonesAuthor Commented:
The code provided in the link works with Visual Studio 2017 with the exception that the pragma is not defined. You get a warning. With  MinGW-64 the following code works (you have to compile with the flag -fsignaling-nans)

int main ()
{
            fpeInit_ fenv_t fe;
            int fint;
           feholdexcept(&fe);
           feclearexcept (FE_ALL_EXCEPT);


          int = fetestexcept(FE_ALL_EXCEPT);
          if (fint & FE_DIVBYZERO ||  fint & FE_INVALID   ||   fint & FE_OVERFLOW  ||  fint & FE_UNDERFLOW)
          {
                 feclearexcept (FE_ALL_EXCEPT);
                 feupdateenv(&fe);
                 
        }


}
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.