强制gfortran首先停止编程NaN
问题描述:
要调试我的应用程序(fortran 90),我想将所有NaN都转换为NaN信号。强制gfortran首先停止编程NaN
使用默认设置我的程序没有任何信号,只输出文件中的NaN数据。我想找到生成NaN的点。如果我可以用信号NaN重新编译程序,我会在第一个错误的浮动操作驻留的第一点得到一个SIGFPE
信号。
答
您正在查找的国旗是-ffpe-trap=invalid
;我通常会添加,zero,overflow
来检查相关的浮点异常。
program nantest
real :: a, b, c
a = 1.
b = 2.
c = a/b
print *, c,a,b
a = 0.
b = 0.
c = a/b
print *, c,a,b
a = 2.
b = 1.
c = a/b
print *,c,a,b
end program nantest
然后编译它,并在调试器中运行它给出:
$ gfortran -o nantest nantest.f90 -ffpe-trap=invalid,zero,overflow -g -static
$ gdb nantest
[...]
(gdb) run
Starting program: /scratch/ljdursi/Testing/fortran/nantest
0.50000000 1.0000000 2.0000000
Program received signal SIGFPE, Arithmetic exception.
0x0000000000400384 in nantest() at nantest.f90:13
13 c = a/b
Current language: auto; currently fortran
随着英特尔Fortran编译器(ifort),使用选项-fpe0
会做同样的事情。
这对C/C++代码来说有点窍门;我们必须实际插入一个调用feenableexcept()
,这会启用浮点异常,并在fenv.h
中定义;
#include <stdio.h>
#include <fenv.h>
int main(int argc, char **argv) {
float a, b, c;
feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
a = 1.;
b = 2.;
c = a/b;
printf("%f %f %f\n", a, b, c);
a = 0.;
b = 0.;
c = a/b;
printf("%f %f %f\n", a, b, c);
a = 2.;
b = 1.;
c = a/b;
printf("%f %f %f\n", a, b, c);
return 0;
}
但效果是一样的:
$ gcc -o nantest nantest.c -lm -g
$ gdb ./nantest
[...]
(gdb) run
Starting program: /scratch/s/scinet/ljdursi/Testing/exception/nantest
1.000000 2.000000 0.500000
Program received signal SIGFPE, Arithmetic exception.
0x00000000004005d0 in main (argc=1, argv=0x7fffffffe4b8) at nantest.c:17
17 c = a/b;
无论哪种方式,您对其中的错误存在的一个更好的处理。
嗨,是否有可能有相同的选项适用于g ++? – osgx 2011-04-24 23:34:58
用g ++很难,但是可以在浮点错误上设置陷阱 - http://trac.hackerwithin.org/wiki/Articles/GccFpe – 2011-04-25 01:40:33