1

The following simple code:

program small_test
double precision :: a, b, c, d 
open(5,file='infile.dat',status='old')
READ (5,*) a, b, c, d
print *, a, b, c, d
end program

works just fine when I compile with gfortran, no trap flags:

$> gfortran  small_test.f90

The input data is

0.087266463 0.087266463   3. 100.

and the output is

   8.7266463000000002E-002   8.7266463000000002E-002   3.0000000000000000        100.00000000000000

as expected.

But when I compile to trap floating point errors,

gfortran -ffpe-trap=invalid,zero,overflow,underflow,precision,denormal -fdump-core small_test.f90

the code fails with error

Program received signal SIGFPE: Floating-point exception - erroneous arithmetic operation.

How could this simple code possibly produce an error?

(What's really going on is that I am debugging a much larger code and I need the traps to find some problem somewhere else in the code. But I need to get past this trivial input statement, where they are tripping me up somehow.)

bob.sacamento
  • 6,283
  • 10
  • 56
  • 115
  • @HighPerformanceMark Typo. Fixed it. – bob.sacamento Jan 08 '19 at 17:48
  • EOL. It is a linux file, not DOS, if that is what you are wondering about. – bob.sacamento Jan 08 '19 at 18:06
  • 1
    The error occurs in the `READ` statement, and the relevant flag is `-ffpe-trap=precision`. Perhaps it is something to do with the conversion of the text representation of the numbers to the internal floating point representation. – Warren Weckesser Jan 08 '19 at 18:25
  • The error also occurs with `-ffpe-trap=inexact`. Maybe `precision` is an alias for `inexact`; I don't see `precision` in https://gcc.gnu.org/onlinedocs/gfortran/Debugging-Options.html#Debugging-Options. – Warren Weckesser Jan 08 '19 at 18:31
  • @WarrenWeckesser Agree. Thanks. This is a surprise to me. I have tried fixing it with formatted input using a "D" descriptor, but it doesn't help. If you want to turn your comment into an answer, I will accept it. And of course, if you have ideas about how to fix this, that would be even better! – bob.sacamento Jan 08 '19 at 18:31
  • Possible duplicate: https://stackoverflow.com/questions/42098438/floating-point-exception-when-reading-real-values-from-an-input-file – Warren Weckesser Jan 08 '19 at 18:32
  • @WarrenWeckesser `precision` is discussed in the gfortran man page. Don't know why it wouldn't be in the on line docs. – bob.sacamento Jan 08 '19 at 18:32
  • 1
    *"If you want to turn your comment into an answer, I will accept it."* Do you agree that the question that I linked to is close enough to yours that this question can be considered a duplicate? – Warren Weckesser Jan 08 '19 at 18:37
  • 1
    @WarrenWeckesser Yes, I think so. – bob.sacamento Jan 08 '19 at 18:41
  • OK then, I will connect them. – Vladimir F Героям слава Jan 08 '19 at 18:53
  • The old answer does not actually show how to use modern Fortran facilities to manipulate the floating exceptions. – Steve Jan 08 '19 at 19:02
  • @Steve, it would be better to add an answer to that other question. – francescalus Jan 08 '19 at 19:23
  • 1
    @bob.sacamento: precision is a (deprecated) alias for inexact. Thus it has been removed from the manual, but it's till accepted for backwards compatibility. The online manual you linked to is to the latest development version, whereas your man page presumably corresponds to the version of gfortran you have installed. If you gfortran is old enough, the man page still mentions precision. – janneb Jan 09 '19 at 07:28
  • @janneb Thanks for the information! – bob.sacamento Jan 10 '19 at 15:30

1 Answers1

2

If you really think that you want to enable floating-point traps on ieee_inexact, then you should probably use the facilities provided by the Fortran language to control the exception instead of a compiler option. Try

program small_test
   use ieee_arithmetic
   implicit none
   double precision :: a, b, c, d
   logical flag
   open(5,file='infile.dat',status='old')
   if (ieee_support_flag(ieee_inexact)) then
      call ieee_get_halting_mode(ieee_inexact, flag)
      call ieee_set_halting_mode(ieee_inexact, .false.)
   end if
   read (5,*) a, b, c, d
   print *, a, b, c, d
   if (ieee_support_flag(ieee_inexact)) then
      call ieee_set_halting_mode(ieee_inexact, flag)
   end if
end program
Steve
  • 301
  • 1
  • 3