使用errno,我试图检查cmath函数是否产生有效的结果,但即使在sqrt()或log()中输入负值,errno仍保持值0,有人知道为什么吗?
环境是macOS Monterey版本12.6.1,编译器是gcc版本11.3.0(Homebrew GCC 11.3.0_1)或苹果clang版本14.0.0(clang-1400.0.29.202)(我试了两个编译器),编译命令是g++ test_errno.cpp -o test_errno -std=c++14
。
我试过的那段代码是直接从this page复制过来的,下面是代码。
#include <iostream>
#include <cmath>
#include <cerrno>
#include <cstring>
#include <clocale>
int main()
{
double not_a_number = std::log(-1.0);
std::cout << not_a_number << '\n';
if (errno == EDOM) {
std::cout << "log(-1) failed: " << std::strerror(errno) << '\n';
std::setlocale(LC_MESSAGES, "de_DE.utf8");
std::cout << "Or, in German, " << std::strerror(errno) << '\n';
}
}
其结果没有打印错误消息,如果errno设置正确,则应该打印错误消息。
2条答案
按热度按时间xiozqbni1#
似乎在macOS上,errno没有被使用,从this bug report到@GAVD的注解。我可以通过math_errhandling的值从@Pete Becker的注解中检查。似乎在C/C++中有两种数学错误处理方式,要么使用errno,要么使用浮点异常,如上面的第二个链接所示。我们可以检查哪种方式系统的数学库通过检查宏常量
math_errhandling
是否等于MATH_ERREXCEPT
或MATH_ERRNO
来使用(或两者),如下所示(从第二个链接复制):在我的系统上,输出是
,这意味着系统不使用errno来报告数学错误,而是使用浮点异常。这就是为什么errno无论如何都保持值0的原因,我应该使用
std::fetestexcept()
来检查错误条件。例如,对于浮点异常,std::feclearexcept(FE_ALL_EXCEPT);
对应errno = 0;
,std::fetestexcept(FE_DIVBYZERO)
对应errno == ERANGE
。yjghlzjz2#
我将在黑暗中尝试一下,猜你在你的构建中启用了快速数学?
没有快速数学:
https://godbolt.org/z/vMo1P7Mn1
快速数学:
https://godbolt.org/z/jEsGz7n38
cmath中的错误处理往往会破坏向量化和constexpr (设置外部全局变量,是破坏这两种情况的副作用)。因此,您通常最好自己检查域错误...