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'
(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.
(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. >
(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)
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.
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.
(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.
Closing as invalid. If anyone sees a reason to re-open, please let me know.