I am re-compiling with IVF 2019 some legacy code written in Fortran 77 and previously compiled with an old version of Lahey Fortran. The problem occurs after reading a record from a third party direct access file and trying to convert a string variable to an integer. The error message is issued at an internal file read statement. The message reads: "forrtl: severe (268): end of record during read, unit -5, file Internal Formatted Read".
Following is the text to a simple program which reproduces the error:
Program TestProg Character AstcomFile*127, Asix*6 Integer J, Ifour, Iasix AstcomFile(1:) = "C:\Users\Jerry\Documents\Visual Studio 2017\" AstcomFile(1:) = AstcomFile(1:Len_Trim(AstcomFile)) // > "Projects\Test\Test\Resources\Dastcom3" J = Len_Trim(AstcomFile) Open (Unit = 4, File = AstcomFile(1:J), Access = 'Direct', > Form = 'Unformatted', Status = 'Old', Recl = 395) Read (4, Rec = 1) Ifour, Asix Write (*, '(A)') Asix Read (Asix, '(I6)') Iasix stop end
The error occurs on the statement immediately preceding 'Stop'. The write statement displays on the console the correct value of Asix. I was able to avoid the error by concatenating Asix to a leading blank in a seven-character string and then converting that seven-character string to the six digit integer. Since there are six characters in the Asix string, I would think there should be no end of record encountered with the read. Is this the normal operating procedure for the IVF compiler?
Much depends on the contents of the data file Dastcom3. I created a 395-byte file with an arbitrary 4-byte integer at the beginning, followed by a 391-byte string starting with byte values (in hex) 31 32 33 34 35 30. The program ran normally.
I created a new direct access file named MyFile (no extension) with a single record of 395 bytes, which is attached in compressed form. The file should be placed in the current working directory of the project. The record contains the same information as the first record of the original third party file. In order, the record contains a 32-bit integer, three 6-character strings that are numeric, a 143-byte string that serves as a spacer to the final 32-bit integer. The revised program to retrieve from the file follows:
Program TestProg Character MyFile*127, D*143 Character*6 A, B, C Integer J, I_1, I_2, Iasix MyFile(1:) = "MyFile" J = Len_Trim(MyFile) Open (Unit = 4, File = MyFile(1:J), Access = 'Direct', > Form = 'Unformatted', Status = 'Old', Recl = 395) Read (4, Rec = 1) I_1, A, B, C, D, I_2 Close (4) Write (*, '(A, I)') 'I_1 = ', I_1 Write (*, '(2A)') 'A = ', A Write (*, '(2A)') 'B = ', B Write (*, '(2A)') 'C = ', C Write (*, '(2A)') 'D = ', D Write (*, '(A, I)') 'I_2 = ', I_2 Read (A, '(I6)') Iasix Pause stop end
The six write statements confirm that the file is being read properly. The end of record error occurs at the read statement following the last write statement. The answer by Steve Lionel to another topic that Ferdinand T. referenced seems to address this topic also, but I don't know what Pad = No is referring to.
That very well may be. The link posted by Ferdinand T. above indicates that the problem was a compiler bug that was corrected in version 19.1. It may have been corrected also in 19.0.5. The problem is that I have 19.0.4 and it is definitely a problem with that version. Unfortunately, my support license expired before 19.0.5 was released, so I will use a workaround that I developed that uses a custom function to make the conversion. Thanks to all for your help, especially Ferdinand T. who posted the link to Steve Lionel's earlier solution to the same problem.
When testing on the different versions of IVF, did you have F77 run-time compatibility enabled? I had it enabled when the error occurred. When disabled, it runs fine in debug configuration, but leads to a handled exception in release configuration. I'm investigating that now. I'm not sure if the compatibility should be enabled or not since the entire program is written in Fortran 77.
As noted in the other thread, /f77rtl is needed to see this misbehavior. You do not need this option unless your program relies on certain semantic differences between F77 and F90, such as the default treatment of blanks in numeric input. Your program may be Fortran 77, but it is also Fortran 2018, and you don't need /f77rtl.