Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28789 Discussions

Backspace command confusion between Compaq and Intel Fortran

Marr__David
Beginner
1,199 Views
Hello, I am working with legacy fortran code that uses the backspace command to read a CSV file that has the following contents:

$Units,

SI,

$Independent variable,

0,10000

$Dependent variable,

5,5

When running the Compaq compiler, two backspace calls are required to move back/up a single line whereas only a single backspace call is required to move back one line in Intel Fortran. I'd prefer not edit the old code, so the real question is: Is there an Intel Fortran option I'm missing that would make my Intel fortran compiler backspace command work in the same way as the Compaq compiler backspace command?

OS: Windows 7 64 bit
CVF 6.1.0
Intel: 12.1.3526.2010 with VS2010
File Open call: open (CurvFileID,file=CurveName,iostat=ierr,mode='read',status='old')

Thanks for any help!

0 Kudos
6 Replies
Steven_L_Intel1
Employee
1,199 Views
No, there isn't. My guess is that we fixed a bug where CVF did not obey the standard. Can you post a short but complete program that demonstrates the difference?

Did your CVF project have the "/vms" option set?
0 Kudos
Marr__David
Beginner
1,199 Views
Sorry to say I cannot find in my Compaq project where the /vms option is (my first time running Compaq was for this code), but I cannot find its use anywhere. Here is, as they say, the short short version of the code. Note that, in Compaq, the first Backspace call does not seem to actually backspace my CSV file at all (when checking with a read call) but each following call to backspace operates the same way in which the Intel Backspace calls does. I could just change the code to a single backspace call for Intel but it occurs in numerous places so would be easiest to get to the bottom of the problem in case there is another, simpler,solution. Thanks again!

[fortran] character*200 CurveName character*200 longline character*2 units integer length, i, nx real*8, allocatable :: CurveData(:,:) parameter (CurvFileID = 100) !c open curve file CurveName = "C:DATA.csv" open (CurvFileID,file=CurveName,iostat=ierr,mode='read',status='old') !c check if there are 6 lines in the curve data file do i = 1, 6 read (CurvFileID,*,iostat=ierr) end do rewind(CurvFileID) !Rewind back to beginning !c read unit read (CurvFileID,*) !read $units read (CurvFileID,*) units !read SI !c read independent variable read (CurvFileID,*) !read $Independent variable, nx = 1 !Find number of ,'s do while (.true.) read (CurvFileID,200,advance='no',iostat=ierr) longline !read 0,1000 length = len_trim (longline) do i = 1, length if (longline(i:i) == ',') nx = nx + 1 end do end do !c back to independent variable data line backspace(CurvFileID) backspace(CurvFileID) allocate(CurveData(nx,2),stat=ierr) !This reads "0,10000" in Compaq but reads "$Independent variable" in Intel read (CurvFileID,*,iostat=ierr) (CurveData(i,1),i=1,nx) !c read dependent variable read (CurvFileID,*) read (CurvFileID,*,iostat=ierr) (CurveData(i,2),i=1,nx) !c end reading curve file close (CurvFileID) deallocate(CurveData) 200 format (A) end[/fortran]
0 Kudos
Steven_L_Intel1
Employee
1,199 Views
I had to tweak your program a bit because, as written, it would loop indefinitely in the DO WHILE (.TRUE.) as nothing breaks out from the loop. I added a test for an EOF condition to do so.

But the result I get then doesn't match your description, so I think I need to ask you to post an edited version of the program that demonstrates the problem and prints things I can look at. Please also attach data.csv as a file - I don't trust that your pasting the content does the right thing.

I will comment that if you read to the end of the file, so that you get an EOF condition, you are positioned past the "endfile record", which may or may not be represented physically in the file. If you then do a BACKSPACE, you are positioned before the ENDFILE record, not before the last record. This is what the standard requires.
0 Kudos
Marr__David
Beginner
1,199 Views
Sorry for the trouble, seems I made the code a bit too short :) Here is the longer version that can be pasted into either the Intel or Compaq versions of the compilerto test and prints to the command window. I've commented out the external function calls and the CSV file is attached (if I've done it correctly). Thanks again[fortran] implicit real*8 (a-h,o-z) character*200 CurveName character*200 longline character*80 err_mess character*4 ext character*2 units integer length, i, nx, idx_s, idx_c real*8 Var_s, Var_c real*8 CurFun real*8, allocatable :: CurveData(:,:) parameter (CurvFileID = 100) parameter (nDimCurv = 2) ! dimension of CurveData !c open curve file CurveName = "C:DATA.csv" open (CurvFileID,file=CurveName,iostat=ierr,mode='read',status='old') !c read curve !c check if there are 6 lines in the curve data file do i = 1, 6 read (CurvFileID,*,iostat=ierr) if (ierr /= 0) then err_mess = 'Error reading Curve File.' !call PRINT_ERROR (err_mess,1) endif end do rewind(CurvFileID) !Rewind back to beginning !c read unit read (CurvFileID,*) !read $units read (CurvFileID,*) units !read SI !call UPPER_CASE(units) if (units /= 'SI' .and. units /= 'IP') then err_mess = 'Unit error in Curve file.' !call PRINT_ERROR (err_mess,1) endif !c read independent variable read (CurvFileID,*) !read $Independent variable, nx = 1 do while (.true.) read (CurvFileID,200,advance='no',iostat=ierr) longline !read 0,1000 length = len_trim (longline) do i = 1, length if (longline(i:i) == ',') nx = nx + 1 end do !c check if the line end met if (ierr /= 0) exit end do !c back to independent variable data line backspace(CurvFileID) backspace(CurvFileID) allocate(CurveData(nx,nDimCurv),stat=ierr) !c check if CurveData has been allocated if (ierr /= 0) then err_mess = 'Can''t allocate array. -- Out of memory.' !call PRINT_ERROR (err_mess,1) end if read (CurvFileID,*,iostat=ierr) (CurveData(i,1),i=1,nx) !This is the issue print *,'Should be 0 (is for Compaq, and is for Intel if a backspace is removed)' print *,CurveData(1,1) print *,'Should be 10000 (is for Compaq, and is for Intel if a backspace is removed)' print *,CurveData(2,1) if (ierr /= 0) then err_mess = 'Error reading Curve File.' !call PRINT_ERROR (err_mess,1) endif !c read dependent variable read (CurvFileID,*) read (CurvFileID,*,iostat=ierr) (CurveData(i,2),i=1,nx) if (ierr /= 0) then err_mess = 'Error reading Curve File.' !call PRINT_ERROR (err_mess,1) endif !c end reading curve file close (CurvFileID) deallocate(CurveData) 200 format (A) end[/fortran]
0 Kudos
John_Campbell
New Contributor II
1,199 Views

David,

It appears to me that you managed to do a work-around for a past bug in CVF.

Now that it has been fixed, you want a compiler option to "Restore old bugs". Relying on compiler options for non-standard implementations is not portable, although portability is becoming old fashioned.

This is similar to the problem of wanting to be backward compatible to old compiler extensions which no longer are compatible with the latest Fortran standard.
I hope the answer is to fix the code !

John

0 Kudos
Steven_L_Intel1
Employee
1,199 Views
I'm inclined to agree with John - you are expecting incorrect behavior. Thanks for the full program, it helps explain things better.

After the DO WHILE loop, the file is positioned "after the record just read", which is after the "0,10000", but that is still the "current record". The first backspace "causes the file ... to be positioned before the current record, if there is a current record, or before the preceding record if there is no current record." So the first backspace takes us to the beginning of the "0,10000" record. The second backspace takes us to the "$Independent variable," record.

I'm at a loss to understand what CVF did here, but it is definitely wrong.
0 Kudos
Reply