【发布时间】:2020-03-18 08:27:30
【问题描述】:
我正在努力尝试以便携式方式设置 std::fenv。
基于this cppreference 页面,fesetexceptflag(const std::fexcept_t*,int) 似乎应该帮助我解决问题。另一方面,我发现 GNU 也提供了feenableexcept(int) 函数。我的理解是 feenablexcept 是 GNU 特定的,虽然我非常可能总是可以访问 GNU 的东西,但我希望只使用 std 的东西,也就是说,坚持使用 @987654325 @。
我写了一个小测试,发现feenableexcept 方法有效,而fesetexceptflag 方法无效。这是两个例子。交换main开头两行的cmets,得到版本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 具有 0 掩码 fenv,但成功提高了 SIGFPE。我很困惑。
如果有帮助的话,我正在一台 linux 机器 (Red Hat) 上使用 gcc 8.2.0。
【问题讨论】: