📅 2015-Jan-05 ⬩ ✍️ Ashwin Nanjappa ⬩ 🏷️ cpp, error, math ⬩ 📚 Archive
Math functions provided by the standard C++ library are defined in the
cmath header file. Many of these functions require their input values to be in a specific domain. For example, the
log function requires its input to be greater than zero.
log(0) is not defined mathematically. The result of such a call is set to a special
-inf value. However, no exception is thrown and the call has actually failed silently. Note that this does not affect the correctness of future math function calls.
There is no warning option provided by GCC that can be enabled to detect such errors in the code. Nor is there any compiler option to enable the standard C++ library to thrown an exception, say
std::domain_error, when such an error occurs. Other libraries, like Boost, do throw such exceptions.
The only way to prevent these math errors is to check the bounds of the inputs passed to these functions. For example, you can write a wrapper function for each of such math functions that does the bounds checking and throws error or exception when the input is wrong. You can change your code to explicitly use only these math wrapper functions instead of those from
If the performance of this math code is important to you, then inline this function and enable the bounds checking only in Debug mode or when you want to check the correctness of some inputs. Disable the checking for Release mode.
When a math function is executed with wrong input, the
errno variable from the
cerrno header file is set to non-zero value. The list of error values can be seen here. Specifically, for math errors, it might be set to either
EDOM. This refers to a range or domain error respectively. To get the error string explaining the error, use the
// Checking for math error in C++ #include <cerrno> #include <cmath> #include <cstring> #include <iostream> std::cout << log(0) << std::endl; if (errno) std::cout << std::strerror(errno) << std::endl; if (errno == EDOM) std::cout << "Domain error\n"; if (errno == ERANGE) std::cout << "Range error\n";
Reference: Section 40.3, The C++ Programming Language (4 Ed) by Stroustrup
Tried with: GCC 4.9.2 and Ubuntu 14.04