gpt4 book ai didi

C++设置浮点异常环境

转载 作者:行者123 更新时间:2023-12-01 14:48:29 26 4
gpt4 key购买 nike

我正在努力尝试以一种可移植的方式设置 std::fenv。

基于 this cppreference 页面,似乎 fesetexceptflag(const std::fexcept_t*,int) 应该可以帮我解决这个问题。另一方面,我发现 GNU 还提供了 feenableexcept(int) 函数。我的理解是 feenableexcept 是特定于 GNU 的,虽然我非常可能总是可以访问 GNU 的东西,但我希望只使用 std 的东西,也就是说, 坚持使用 fesetexceptflag。我写了一个小测试,发现 feenableexcept 方法有效,而 fesetexceptflag 方法无效。这是两个例子。交换main开头两行的注释,得到版本1(fesetexceptflag)和版本2(feenableexcept):

#include <cfenv>
#include <csignal>
#include <cstdio>

void signal_handler (int signum) {
printf ("signal %d caught.\n",signum);
exit(1);
}

int main(int,char**){
std::fexcept_t my_flag = FE_DIVBYZERO;
fesetexceptflag(&my_flag,FE_ALL_EXCEPT); // Uncomment this for version 1
// feenableexcept(my_flag); // Uncomment this for version 2

int mask = fetestexcept(FE_ALL_EXCEPT)
printf("current mask: %d\n",mask);
printf("mask is FE_DIVBYZERO: %s\n",mask==FE_DIVBYZERO ? "yes" : "no");
signal(SIGFPE, signal_handler);

double one = 1.0;
double zero = 0.0;
double my_inf = one/zero;
printf("All done!\n");
return 0;
}

版本 1 输出:

current mask: 4
mask is FE_DIVBYZERO: yes
All done!

版本 2 输出:

current mask: 0
mask is FE_DIVBYZERO: no
signal 8 caught.

因此版本 1 似乎在 fenv 中正确设置了异常标志,但未能引发 SIGFPE,而版本 2 未设置异常标志,但确实引发了 SIGFPE。这里发生了什么事?我是否误解了 fesetexceptflag 的文档?我的理解是它获取第一个 arg 中在第二个 arg 中处于事件状态的所有位,并将它们放入 fenv(这似乎是发生的事情)。但是,这似乎无效。另一方面,版本 2 的掩码 fenv 为 0,但仍成功提高了 SIGFPE。我很困惑。

我在 linux 机器 (Red Hat) 上使用 gcc 8.2.0,如果有帮助的话。

最佳答案

Am I misinterpreting the documentation of fesetexceptflag?

是的。 fesetexceptflag 意思是:设置这个异常标志来表示已经报告了异常。

fetestexcept 的正确用法是:

feclearexcept(FE_ALL_EXCEPT);
int mask = fetestexcept(FE_ALL_EXCEPT);
printf("current mask: %d\n",mask);
printf("FE_DIVBYZERO before: %s\n",std::fetestexcept(FE_DIVBYZERO) ? "yes" : "no"); // no
double my_inf = one/zero;
int mask = fetestexcept(FE_ALL_EXCEPT);
printf("current mask: %d\n",mask);
printf("FE_DIVBYZERO after: %s\n",std::fetestexcept(FE_DIVBYZERO) ? "yes" : "no"); // yes

没有使浮点异常引发信号的标准方法。这就是 glibc 为您提供的功能。不过,您可以自己发出信号:

if (fetestexcept(FE_ALL_EXCEPT))
raise(SIGFPE);

关于C++设置浮点异常环境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60731382/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com