[Bug fortran/100954] writing to a character opens unit -10

kargl at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Jun 8 02:26:20 GMT 2021


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100954

kargl at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kargl at gcc dot gnu.org

--- Comment #1 from kargl at gcc dot gnu.org ---
(In reply to Taco Jerkface from comment #0)
> Sample code:
> 
> program inquire
>       implicit none
>       logical opened
>       character(len=256) filename
>       character(len=4) charstring
> 
>       integer iounit, itmp, ierr
> 
>       filename='testfile'
> 
>       iounit=-10
>       inquire(iounit, opened=opened,iostat=ierr)
>       ! not open yet
>       write(*,*) 'Unit',iounit,'open?',opened,ierr

I believe the above is invalid Fortran.  Fortran 2018, pp. 216-218

  R1201 io-unit           is file-unit-number
  R1202 file-unit-number  is scalar-int-expr

  A unit is either an external unit or an internal unit. An external unit
  is used to refer to an external file and is specified by an asterisk or
  a file-unit-number. The value of file-unit-number shall be nonnegative,
  equal to one of the named constants INPUT_UNIT, OUTPUT_UNIT, or ERROR_UNIT
  of the intrinsic module ISO_FORTRAN_ENV (16.10.2), the unit argument of an
  active defined input/output procedure (12.6.4.8), or a NEWUNIT value
  (12.5.6.12).

In the above Fortran code, iounit is negative and it is not a NEWUNIT
value. There is some wiggle room, in that 

  All input/output statements are permitted to refer to units that exist.
  The CLOSE, INQUIRE, and WAIT statements are also permitted to refer to
  units that do not exist. No other input/output statement shall refer to
  a unit that does not exist.

Your code could have done 'inquire(unit=42, opened=opened,iostat=ierr)'
where 42 is nonnegative and refers to a unit that does not exist.  But,
iounit=-10 is negative and does not refer to a unit opened with NEWUNIT.
For NEWUNIT, the Fortran standard requires

  The variable is defined with a processor determined NEWUNIT value...

  A NEWUNIT value is a negative number, and shall not be equal to -1,
  any of the named constants ERROR_UNIT, INPUT_UNIT, or OUTPUT_UNIT from
  the intrinsic module ISO_FORTRAN_ENV (16.10.2), any value used by the
  processor for the unit argument to a defined input/output procedure,
  nor any previous NEWUNIT value that identifies a file that is connected.
  The unit identified by a NEWUNIT value shall not be preconnected.

So, the Fortran standard does not require -10 to be a NEWUNIT value.

> 
>       ! new unit grabs -10
>       open(newunit=iounit,file=trim(filename) )
>       write(*,*) 'Opened unit',iounit
> 
>       ! now -10 is open
>       inquire(iounit, opened=opened,iostat=ierr)
>       write(*,*) 'Unit',iounit,'open?',opened,ierr
> 
>       ! close it
>       close(iounit)
>       write(*,*) 'Closed unit',iounit

The above is conforming as it seems that gfortran has assigned -10
as the unit number via the NEWUNIT mechanism.  However, after the
close statement, there is no NEWUNIT value.

>       ! now -10 is closed
>       inquire(iounit, opened=opened,iostat=ierr)
>       write(*,*) 'Unit',iounit,'open?',opened,ierr

See above as I believe that this is invalid Fortran.

>       itmp=0
>       write(charstring, '(I4.4)') itmp
>       write(*,*) 'wrote into charstring ', trim(charstring)
> 
> 
>       ! now -10 is reported as open again
>       inquire(iounit, opened=opened,iostat=ierr)
>       write(*,*) 'Unit',iounit,'open?',opened,ierr

Invalid code can yield unexpected results.

>       ! trying to close it seg faults
>       if (opened) then
>         close(iounit)
>       endif
> 
> endprogram inquire

Of course, I could be wrong, so I'll leave this for other to pondered.


More information about the Gcc-bugs mailing list