浮点异常在新的gfortran版本中发出信号



我目前正在调试一些软件的子程序,这是我老板在90年代写的。在特定子例程的do循环中似乎出现了一个浮点异常:

16  irad=1,incmax
    rr1=rr2
    rr2=rr2+rdiv
      if(rr1.gt.rlimit) goto 16
      if(pts(irad).gt.0.0) then
         discrm=(rmsden(mt,irad)/pts(irad))
     1          -((average(mt,irad)**2)/(pts(irad)**2))
      else
         discrm=0.0
      endif
      if(discrm.ge.0.0) then
         rmsden(mt,irad)=sqrt(discrm)
      else
         rmsden(mt,irad)=0.0
      endif
      average(mt,irad)=average(mt,irad)/pts(irad)
      average(mt,irad)=(average(mt,irad)*100.0)/bigmost(mt)
      rmsden(mt,irad)=(rmsden(mt,irad)*100.0)/bigmost(mt)
      denbot(mt,irad)=(denbot(mt,irad)*100.0)/bigmost(mt)
      dentop(mt,irad)=(dentop(mt,irad)*100.0)/bigmost(mt)
      iradmax(mt)=irad

 17   if(iverbose0.ge.1) then
         ipts=pts(irad)
         iptszero=ptszero(irad)
         if(ipts.eq.0) then
            average(mt,irad)=0.0
            rmsden(mt,irad)=0.0
            denbot(mt,irad)=0.0
            dentop(mt,irad)=0.0
         endif
         write(6,99) rr1,rr2,ipts,iptszero,average(mt,irad),
     1               rmsden(mt,irad),denbot(mt,irad),dentop(mt,irad)
 99      format(1x,2f9.2,2i8,2f8.1,2f8.1)
      endif
 16   continue
      stop 'PIPPA'
If I put the stop 'PIPPA' statement before "16  continue", the there are no errors. However, if the stop statement goes after the "16  continue", I get: 
Note: The following floating-point exceptions are signalling: IEEE_INVALID_FLAG
STOP PIPPA

在升级GCC编译器/库之前不会发生这种情况。我承认我已经通过谷歌找到了很多资源,但我仍然无法调试这个。我也尝试过编译时的--fpe-trap标志,但是它们不输出任何东西。

为什么gfortran现在报错了?

这里似乎有两个问题。让我们试着回答每个问题。

1。为什么新的GFortran版本打印这样的消息

由于Fortran 2008标准要求STOP和ERROR STOP语句的执行输出当前信号FP异常的列表(如果系统支持这样的事情),GFortran从GFortran 4.9版本开始遵循这一点。参见https://gcc.gnu.org/ml/fortran/2013-06/msg00072.html .

2。为什么我的代码触发这个异常,为什么它只发生在新的GFortran版本

很可能,异常之前也发出了信号,但由于它没有在STOP语句中打印,因此您没有意识到它。由于您所展示的示例不是自包含的(我无法编译和测试它),我只能建议您尝试常用的调试命令行选项,如"-fcheck=all, -ffpe-trap=invalid,zero,overflow -g -Wall -Wextra -Werror -pedantic",检查在valgrind等下运行程序

最新更新