Reputation: 11
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
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