1

In N2137 section 12.3.4.2 it says

An advancing input/output statement always positions a record file after the last record read or written, unless there is an error condition.

In section 12.3.4.4 it says

For nonadvancing input, if no error condition or end-of-file condition occurred, but an end-of-record condition (12.11) occurred, the file is positioned after the record just read.

So I would conclude that reading a record with advancing input and encountering an end-of-record condition reading the same record with nonadvancing input should leave the file position in the same place. Here is a sample program:

program testpos1
   implicit none
   integer iunit
   character(80) lineout
   character(:), allocatable :: linein
   integer i
   integer linelen
   integer pos
   integer size

   open(newunit=iunit,file='testpos1.txt',status='replace')
   do i = 1, 2
      write(lineout,'(*(g0))') i,' line ',i
      write(iunit,'(*(g0))') trim(lineout)
   end do
   close(iunit)
   linelen = len_trim(lineout)
   allocate(character(linelen) :: linein)
   open(newunit=iunit,file='testpos1.txt',status='old',access='stream',form='formatted')
   inquire(iunit,pos=pos)
   write(*,'(*(g0))') 'Position on open = ',pos
   read(iunit,'(a)',advance='no',eor=9999,size=size) linein
   inquire(iunit,pos=pos)
   write(*,'(*(g0))') 'Position after exact read of first line = ',pos
   read(iunit,'(a)',advance='no',eor=10,size=size) linein
   write(*,'(*(g0))') 'Catastrophic failure to hit EOR on line 1'
   stop
10 continue
   inquire(iunit,pos=pos)
   write(*,'(*(g0))') 'Position reading past EOR on first line = ',pos
   rewind(iunit)
   inquire(iunit,pos=pos)
   write(*,'(*(g0))') 'Position on rewind = ',pos
   read(iunit,'()')
   inquire(iunit,pos=pos)
   write(*,'(*(g0))') 'Position after advancing read of first line = ',pos
   rewind(iunit)
   deallocate(linein)
   allocate(character(linelen+1) :: linein)
   inquire(iunit,pos=pos)
   write(*,'(*(g0))') 'Position on rewind = ',pos
   read(iunit,'(a)',advance='no',eor=20,size=size) linein
   write(*,'(*(g0))') 'Catastrophic failure to hit EOR on line 1'
   stop
20 continue
   inquire(iunit,pos=pos)
   write(*,'(*(g0))') 'Position reading past EOR on first line = ',pos
   stop
9999 continue
   write(*,'(*(g0))') 'Catastrophic EOR after reading ',size,' bytes'
end program testpos1

Output with gfortran 8.1.0

Position on open = 1
Position after exact read of first line = 9
Position reading past EOR on first line = 11
Position on rewind = 1
Position after advancing read of first line = 11
Position on rewind = 1
Position reading past EOR on first line = 11

This is what I expected. But ifort 16.0.2 says

Position on open = 1
Position after exact read of first line = 9
Position reading past EOR on first line = 9
Position on rewind = 1
Position after advancing read of first line = 11
Position on rewind = 1
Position reading past EOR on first line = 9

So I take it that this is a bug in ifort? Is it fixed in the latest version?

francescalus
  • 30,576
  • 16
  • 61
  • 96
user5713492
  • 954
  • 5
  • 11
  • @HighPerformanceMark No, this issue cropped when composing the answer https://stackoverflow.com/a/51371461/5713492 and the `g0` formats only occur on writing anyhow. The problem seems to be that `ifort` isn't getting past the `<0Dh><0Ah>` at the end of the record on nonadvancing reads. – user5713492 Jul 18 '18 at 10:46

0 Answers0