Platonist_Platypus
Platonist_Platypus

Reputation: 11

Cerrno not working, but strerror working, in Xcode (11.6)


Edit: Strerror appears to work. E.g., if errno = ERANGE, it outputs "Result too large".

The problem remains that errno is not changed from 0.


In Xcode, I've been trying out cerrno and strerror with the short code below. Xcode returns

sqrt(-1) = nan

Undefined error: 0

instead of

sqrt(-1) = -nan

Numerical argument out of domain,

as does, for example, cpp.sh.

Why is this happening?

#include <iostream>
#include <iomanip>
#include <cmath>
#include <cerrno>
#include <cstring>

using namespace std;

int main() {

  errno = 0;
  cout << "sqrt(-1) = " << sqrt(-1) << endl;
  cout << strerror(errno) << endl << endl;
       
  return(0); 
}

Upvotes: 1

Views: 158

Answers (1)

Bitwize
Bitwize

Reputation: 11220

Whenever you want to check errno after an operation, you should always check it, and possibly store it, immediately after the operation that sets it. If you perform other function calls in between that check, even something as simple as printing to the terminal, you may be clobbering errno.

One possible reason why errno is becoming 0 is due to the fact that it is wrapped in the stream expressions, and there's no guarantee that iostream does not indirectly set (or unset) errno through its implementation.

If ever you want to check or print the errno reason, you will always want to store the result before you print it. For example:

#include <iostream>
#include <iomanip>
#include <cmath>
#include <cerrno>
#include <cstring>

int main() {

  errno = 0;
  
  // store errno immediately after the computation
  const auto result = std::sqrt(-1);
  const auto err = errno;

  // then print
  std::cout << "sqrt(-1) = " << result << std::endl;
  std::cout << std::strerror(err) << std::endl << std::endl;
       
  return 0; 
}

Edit: From the discussions in the OP's comments, this appears to not be the reason for errno not being set -- but rather due to math_errhandling being set to 2. I am keeping this answer here for archival reasons, since the code in the original post could just as easily be seeing this result for the reasons described here.

Upvotes: 2

Related Questions