Bug 37129 - Problems with access='direct', recl=1 I/O
Summary: Problems with access='direct', recl=1 I/O
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.4.0
: P3 normal
Target Milestone: ---
Assignee: Jerry DeLisle
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-08-15 14:15 UTC by Joseph A. Huwaldt
Modified: 2008-08-19 02:40 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-08-16 22:48:43


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joseph A. Huwaldt 2008-08-15 14:15:45 UTC
In porting legacy Fortran 77 code to gfortran, I encountered an issue that can be boiled down and reproduced with the following code:

       INTEGER*4 HDRPOS,CURPOS
      
      OPEN(UNIT= 9,FILE='fort.9',ACCESS='DIRECT', STATUS='NEW',
     &     FORM='UNFORMATTED',RECL=1)     

      INQUIRE(UNIT=9, NEXTREC=HDRPOS)
      
      WRITE(9,REC=HDRPOS) 1,2,3
      
      INQUIRE(UNIT=9, NEXTREC=CURPOS)
      WRITE(9,REC=CURPOS) dble(4),dble(5),dble(6)
      
      END

Historically, g77 compiles and runs this code with the behavior expected by the original authors of the program; a set of three 4 byte integer values are written followed by a set of three 8 byte double values.  gfortran compiles the code without warning, but at runtime gives the error:

At line 8 of file test.f (unit = 9, file = 'fort.9')
Fortran runtime error: Write exceeds length of DIRECT access record

It appears that gfortran does not interpret recl=1 the way many historic compilers, including g77, did.  So, this bug report is to request that recl=1 be interpreted to mean that the compiler should use the I/O list to determine how many items to read or write as g77 apparently did.



Detailed information on my setup follows:

gfortran -v -save-temps -Wall test.f 
Driving: gfortran -mmacosx-version-min=10.5.4 -v -save-temps -Wall test.f -lgfortranbegin -lgfortran -shared-libgcc
Using built-in specs.
Target: i386-apple-darwin9.2.0
Configured with: ../gcc-4.4-20080509/configure --enable-languages=fortran,c++
Thread model: posix
gcc version 4.4.0 20080509 (experimental) (GCC) 
COLLECT_GCC_OPTIONS='-mmacosx-version-min=10.5.4' '-v' '-save-temps' '-Wall' '-shared-libgcc' '-mtune=generic'
 /usr/local/libexec/gcc/i386-apple-darwin9.2.0/4.4.0/f951 test.f -ffixed-form -fPIC -quiet -dumpbase test.f -mmacosx-version-min=10.5.4 -mtune=generic -auxbase test -Wall -version -fintrinsic-modules-path /usr/local/lib/gcc/i386-apple-darwin9.2.0/4.4.0/finclude -o test.s
GNU Fortran (GCC) version 4.4.0 20080509 (experimental) (i386-apple-darwin9.2.0)
	compiled by GNU C version 4.4.0 20080509 (experimental), GMP version 4.2.1, MPFR version 2.2.1.
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
COLLECT_GCC_OPTIONS='-mmacosx-version-min=10.5.4' '-v' '-save-temps' '-Wall' '-shared-libgcc' '-mtune=generic'
 as -arch i386 -force_cpusubtype_ALL -o test.o test.s
COMPILER_PATH=/usr/local/libexec/gcc/i386-apple-darwin9.2.0/4.4.0/:/usr/local/libexec/gcc/i386-apple-darwin9.2.0/4.4.0/:/usr/local/libexec/gcc/i386-apple-darwin9.2.0/:/usr/local/lib/gcc/i386-apple-darwin9.2.0/4.4.0/:/usr/local/lib/gcc/i386-apple-darwin9.2.0/
LIBRARY_PATH=/usr/local/lib/gcc/i386-apple-darwin9.2.0/4.4.0/:/usr/local/lib/gcc/i386-apple-darwin9.2.0/4.4.0/../../../:/usr/lib/
COLLECT_GCC_OPTIONS='-mmacosx-version-min=10.5.4' '-v' '-save-temps' '-Wall' '-shared-libgcc' '-mtune=generic'
 /usr/local/libexec/gcc/i386-apple-darwin9.2.0/4.4.0/collect2 -dynamic -arch i386 -macosx_version_min 10.5.4 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/local/lib/gcc/i386-apple-darwin9.2.0/4.4.0 -L/usr/local/lib/gcc/i386-apple-darwin9.2.0/4.4.0/../../.. test.o -lgfortranbegin -lgfortran -lgcc_s.10.5 -lgcc -lSystem
COLLECT_GCC_OPTIONS='-mmacosx-version-min=10.5.4' '-v' '-save-temps' '-Wall' '-shared-libgcc' '-mtune=generic'
Comment 1 kargls 2008-08-15 16:53:26 UTC
(In reply to comment #0)
 
> It appears that gfortran does not interpret recl=1 the way many historic
> compilers, including g77, did.  So, this bug report is to request that recl=1
> be interpreted to mean that the compiler should use the I/O list to determine
> how many items to read or write as g77 apparently did.

I suspect that gfortran intreprets recl=1 in your open statement
according to the words of the Fortran Standard.   If my reading
of 9.4.5.12 is correct (which can be incorrect), then it appears
the code is nonconforming Fortran and it is a bug in the code
not gfortran.
Comment 2 Joseph A. Huwaldt 2008-08-15 16:58:57 UTC
(In reply to comment #1)

Is there a Fortran 77 compatible work-around that will do what this program was doing (i.e.: write out a mixed set of 4 byte integers and 8 byte floats to a binary file with a specific format since that file will be read by another program that we do not control)?

Joe

> (In reply to comment #0)
> 
> > It appears that gfortran does not interpret recl=1 the way many historic
> > compilers, including g77, did.  So, this bug report is to request that recl=1
> > be interpreted to mean that the compiler should use the I/O list to determine
> > how many items to read or write as g77 apparently did.
> 
> I suspect that gfortran intreprets recl=1 in your open statement
> according to the words of the Fortran Standard.   If my reading
> of 9.4.5.12 is correct (which can be incorrect), then it appears
> the code is nonconforming Fortran and it is a bug in the code
> not gfortran.
> 

Comment 3 kargls 2008-08-15 18:59:39 UTC
(In reply to comment #2)
> (In reply to comment #1)
> 
> Is there a Fortran 77 compatible work-around that will do what this program was
> doing (i.e.: write out a mixed set of 4 byte integers and 8 byte floats to a
> binary file with a specific format since that file will be read by another
> program that we do not control)?

Not that I'm aware of.  I just check the Fortran 77 standard and
the code is definitely nonconforming.  For a file opened with
direct access the F77 standard says:

12.2.4 File Access
12.2.4.2 Direct Access
   ....
   (4) All records of the file have the same length.

12.9.5.1 Unformatted Data Transfer

  On output to a file connected for direct access, the output list must not
  specify more values than can fit into a record.


Now, if you want to use a modern version of Fortran, you may be able to
use access='stream'.  This will allow you to write the values to the 
file as a binary file.

program testing
   open(unit=8, file='out', access='stream')
   write(8) 1, 2, 3
   write(8) dble(1), dble(2), dble(3)
   close(8)
end program testing

mobile:kargl[217] ll out
-rw-r--r--  1 kargl  kargl  - 36 Aug 15 11:57 out

36 bytes = 3 * sizeof(double) + 3 * sizeof(integer)
 
Comment 4 Jerry DeLisle 2008-08-16 22:48:43 UTC
I agree there is legacy g77 behavior involved here.  I did a test here, and a very simple patch will enable this feature.  At least for the test case I get the exact same results as g77.  I just disable this check for RECL=1 and std=legacy.

I am leary about doing this sort of thing and would like to here from others on the team s far as doing this.
Comment 5 Tobias Burnus 2008-08-17 17:59:52 UTC
For completeness, I tested the program with a couple of compilers, which all generated a run-time error message:
- Intel ifort 10 and 11beta
- Sun Studio 12 sunf95
- g95
- Portland pgf77 7.1
- Open64 openf95
- Pathscale 3.1 pathf90

Thus I'm wondering whether it makes really sense to support it with -std=legacy; on the other hand, I don't see off hand how this can break things and thus g77's behaviour with -std=legacy might be possible.
Comment 6 kargls 2008-08-17 19:53:51 UTC
(In reply to comment #4)
> I agree there is legacy g77 behavior involved here.  I did a test here, and a
> very simple patch will enable this feature.  At least for the test case I get
> the exact same results as g77.  I just disable this check for RECL=1 and
> std=legacy.
> 
> I am leary about doing this sort of thing and would like to here from others on
> the team s far as doing this.
> 

Given Tobias' findings with other compilers and the fact that this extension
is not documented in the g77 manual (well at least I can't find it documented),
I'm inclined to state that the code is invalid and g77 has a bug.
Comment 7 Jerry DeLisle 2008-08-19 02:40:29 UTC
Closing as invalid.  If anyone sees a reason to re-open, please let me know.