简体   繁体   中英

errno value is not updated (c++)

I'm new to coding (currently learning c++ & I know a little of C)...

was reading about functions in math.h and read about errno...

According to the site I referred :-

Domain error (input argument is outside the range in which the operation is mathematically defined, eg std::sqrt(-1), std::log(-1), or std::acos(2)). If MATH_ERRNO bit is set, EDOM is assigned to errno. If MATH_ERREXCEPT bit is set, FE_INVALID is raised.

So I tried writing a small program with that knowledge...

#include <iostream>
#include <cerrno>
#include <cmath>
using namespace std;

int main (void)
{
  errno = 0;
  cout<<"\nWhat I get :-\n";
  cout << "log(-3) = " << log(-3) << "\n"; 
  //shouldn't it do (errno = EDOM) in the above step?
  cout << "errno = " << errno << "\n";
  cout << strerror(errno) << "\n";

  errno = EDOM;
  cout<<"\nWhat I want :-\n";
  cout << "log(-3) = " << log(-3) << "\n";
  cout << "errno = " << errno << "\n";
  cout << strerror(errno) << "\n\n";

  return(0);
}

And in the output I see that the errno is not getting updated to EDOM in my first block even though -3 is not in the domain of log()...

Output:-

What I get :-
log(-3) = nan
errno = 0
Undefined error: 0

What I want :-
log(-3) = nan
errno = 33
Numerical argument out of domain

I don't understand what I'm missing here... Plz help....

I'm compiling my code on Apple LLVM version 7.3.0 (clang-703.0.31) in Mac.

#define MATH_ERRNO 1 is illegal. You should not redefine standard library symbols. MATH_ERRNO is already defined as 1 by standard.

You cannot set how implementation handles error (aside from compiler-specific switches. Read documentation for your compiler). You can only check it:

if (math_errhandling & MATH_ERRNO)
    std::cout << "Error reporting uses errno\n";
else 
    std::cout << "Error reporting does not use errno\n";

if (math_errhandling & MATH_ERREXCEPT)
    std::cout << "Error reporting uses floating-point exceptions\n";
else 
    std::cout << "Error reporting does not use floating-point exceptions\n";

For clang, relevant flags are -fmath-errno / -fmath-no-errno to use/not use errno .

From discussion on reported bug it seems, that Mac implementation of standard library doesn't use errno at all. So you are out of luck if you want use it for error reporting.

You can find complete example (in C) of math err handling at: http://www.cplusplus.com/reference/cmath/math_errhandling/ For completness example from that site:

#include <stdio.h>      /* printf */
#include <math.h>       /* math_errhandling */
#include <errno.h>      /* errno, EDOM */
#include <fenv.h>       /* feclearexcept, fetestexcept, FE_ALL_EXCEPT, FE_INVALID */
#pragma STDC FENV_ACCESS on

int main () {
  errno = 0;
  if (math_errhandling & MATH_ERREXCEPT) feclearexcept(FE_ALL_EXCEPT);

  printf ("Error handling: %d",math_errhandling);

  sqrt (-1);
  if (math_errhandling & MATH_ERRNO) {
    if (errno==EDOM) printf("errno set to EDOM\n");
  }
  if (math_errhandling  &MATH_ERREXCEPT) {
    if (fetestexcept(FE_INVALID)) printf("FE_INVALID raised\n");
  }

  return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM