Search code examples
fortranintel-fortran

Cannot detect file existing or not


In a program I am improving, I noticed that Fortran does not detect file existing or not. This led to a logic error which has not been fixed. I highly appreciate if you could point out the problems or errors and give me your corrections.

  open(unit=nhist,file=history,iostat=ierr)!This setting cannot exit program if file does not exist because ierr is always 0
  if (ierr /=0) then
   write(*,*)'!!! error#',ierr,'- Dump file not found'
   stop
  endif

  !I used below statement, the program exits even though a file is existing
       open(unit=nhist,file=history,err=700)
   700 ierr=-1
       if (ierr /=0) then
       write(*,*)'!!! error#',ierr,'- Dump file not found'
       stop
       endif

Solution

  • There are two distinct problems here. Let's look at them separately.

    First, consider

    open(unit=nhist,file=history,iostat=ierr)
    

    The comment suggests that ierr is always set to zero. Well, why shouldn't it be set to zero? ierr should be non-zero in the case the case of an error, but is the file not existing an error?

    Not necessarily. In the absence of a status= specifier the default status='unknown' is taken. The compiler doesn't have to (and is unlikely to) treat opening in this case as an error if the file doesn't exist. It's likely to create it as needed on a write, or complain when trying to read.

    Adding status='old' to the open statement is the usual way of saying "the file should exist".

    Second, consider

           open(unit=nhist,file=history,err=700)
       700 ierr=-1
           if (ierr /=0) then
           ...
    

    If there's an error here, execution is transferred to the statement labelled 700. From this statement ierr is set to a non-zero value and off we go to the if construct to handle that error.

    It's just that the statement labelled 700 also happens to be executed even without an error: it's simply the next statement after the open and there's no branch to miss it. [I could give an example of such branching, but I don't want to encourage use of err= in modern code. With the working iostat= things are far preferable.]

    But if you just wish to test the existence of a file, consider inquire-by-file:

    logical itexists
    inquire (file=history, exist=itexists)
    if (.not.itexists) error stop "No file :("
    

    Some would argue this is even better than having status='old' in an open statement.