- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As you know, whenwe invoke an I/O statement, we can have an ERR= or END= branch.
That has the same effect as putting GO TO statements in the code.
Bearing in mind that the new standards are trying to do away with those, is there a way around this?
Here is a short example:
Read(2,Err=20,End=30)list
! here if normal
! do stuff with I/O items
etc etc etc
go to 40
20 print *,"error"
go to 40
30 print *,"EOF"
40 etc. etc. etc.
It can get pretty messy.
That has the same effect as putting GO TO statements in the code.
Bearing in mind that the new standards are trying to do away with those, is there a way around this?
Here is a short example:
Read(2,Err=20,End=30)list
! here if normal
! do stuff with I/O items
etc etc etc
go to 40
20 print *,"error"
go to 40
30 print *,"EOF"
40 etc. etc. etc.
It can get pretty messy.
Link Copied
8 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
IOSTAT is the suggested method of detecting errors and end-of-file. But there's nothing wrong with END= and ERR= if used in a reasonable fashion. I tend to prefer using IOSTAT and then EXIT a loop if an EOF condition is reached.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When you have a number of read statements, then checking the status may become as messy as
using ERR= and END= in an undisciplined fashion.
read( 10, *, iostat = ierr) a
if ( ierr /= 0 ) then
write(*,*) 'Problem reading a'
stop
endif
using ERR= and END= in an undisciplined fashion.
read( 10, *, iostat = ierr) a
if ( ierr /= 0 ) then
write(*,*) 'Problem reading a'
stop
endif
read( 10, *, iostat = ierr ) b
if ( ierr /= 0 ) then
write(*,*) 'Problem reading b'
stop
endif
...
for instance.
read( 10, *, iostat = ierr, err = 100 ) a
read( 10, *, iostat = ierr, err = 100 ) b
...
... ordinary handling
return
! Error handling
100 continue
write(*,*) 'Oops, something went wrong'
stop
may be more concise and still fairly disciplined. It simply combines both methods.
(But in most cases, I prefer to keep the error handling close to theread statement)
Regards,
Arjen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do you think that a CASE construct with IOSTAT would be
a clean way of doing this?
I guess it depends upon the CASE substructures being mutually exclusive,
which I believe they are for I/O statements.
Or maybe IF-THEN- ELSE would work just as well (?)
I was also thinking about something like:
read(2,IOSTAT=ios)list
If (IOS.ne.0)call errprint(ios)
Where errprint would just print out error messages for unexexpected
conditions, and that little routine would be used everywhere in the code.
IOS has a special value for EOF conditions I believe.
a clean way of doing this?
I guess it depends upon the CASE substructures being mutually exclusive,
which I believe they are for I/O statements.
Or maybe IF-THEN- ELSE would work just as well (?)
I was also thinking about something like:
read(2,IOSTAT=ios)list
If (IOS.ne.0)call errprint(ios)
Where errprint would just print out error messages for unexexpected
conditions, and that little routine would be used everywhere in the code.
IOS has a special value for EOF conditions I believe.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The special value is defined by the constant IOSTAT_END in intrinsic module ISO_FORTRAN_ENV.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think that you are making too much of a legacy feature. As Dr. Fortran has noted, the IOSTAT= argument can be used instead of the older ERR= and END= features. It is really up to you to select a set of features of the language that you are comfortable with.
Even in code that contain ERR=, note that you are not required to use any GOTO statements.
There are a few situations where using a sparingly few GOTO statements may be the best solution, and resorting to contortions in order to avoid them results in code whose awkwardness is painfully obvious.
In other words, make up your own style of programming, but don't let your self-imposed rules suffocate you.
Even in code that contain ERR=, note that you are not required to use any GOTO statements.
There are a few situations where using a sparingly few GOTO statements may be the best solution, and resorting to contortions in order to avoid them results in code whose awkwardness is painfully obvious.
In other words, make up your own style of programming, but don't let your self-imposed rules suffocate you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The issue I mostly consider is:
How easy is it to DEBUG?
Something with lots of GO TO branching is much
harder to mange, so I like the IOSTAT approach.
But I realize there are situations where a GOTO
has to be used.
I just ordered several books about this, so
it'll be interesting to see what they have to say.
How easy is it to DEBUG?
Something with lots of GO TO branching is much
harder to mange, so I like the IOSTAT approach.
But I realize there are situations where a GOTO
has to be used.
I just ordered several books about this, so
it'll be interesting to see what they have to say.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Code with lots of branching, whether controlled by GOTOs and statement labels, or by IF...THEN...ELSE...ENDIF or other branching constructs, is inherently difficult to debug.
Here is an example:
dimension k(5)
...
do i=1,5
if (i .gt. 1 .and. k(i - 1) .lt. 7) then
...
endif
enddo
No GOTO statements or statement labels here. If your compiler is not set to check for out of range subscripts and uninitialized array elements, you may find such a bug difficult to detect.
Here is an example:
dimension k(5)
...
do i=1,5
if (i .gt. 1 .and. k(i - 1) .lt. 7) then
...
endif
enddo
No GOTO statements or statement labels here. If your compiler is not set to check for out of range subscripts and uninitialized array elements, you may find such a bug difficult to detect.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Consider:
With FPP
ierrLine = __LINE__
read( 10, *, iostat = ierr, err = 100 ) a
ierrLine = __LINE__
read( 10, *, iostat = ierr, err = 100 ) b
Without FPP
integer, pragma ierr_Read_a = 1
integer, pragma ierr_Read_b = 2
ierrCode = ierr_Read_a
read( 10, *, iostat = ierr, err = 100 ) a
ierrCode = ierr_Read_b
read( 10, *, iostat = ierr, err = 100 ) b
And in both cases remember to place a break point at the err=nnn line(s) or in a generalized error message printout
100 call errMessage(ierrCode)
... corrective measure for error dispatches reaching here
subroutine errMessage(ierrCode)
integer :: ierrCode
write(*,*) ErrorMessage(i) ! break here
end subroutine errMessage
Jim Dempsey
With FPP
ierrLine = __LINE__
read( 10, *, iostat = ierr, err = 100 ) a
ierrLine = __LINE__
read( 10, *, iostat = ierr, err = 100 ) b
Without FPP
integer, pragma ierr_Read_a = 1
integer, pragma ierr_Read_b = 2
ierrCode = ierr_Read_a
read( 10, *, iostat = ierr, err = 100 ) a
ierrCode = ierr_Read_b
read( 10, *, iostat = ierr, err = 100 ) b
And in both cases remember to place a break point at the err=nnn line(s) or in a generalized error message printout
100 call errMessage(ierrCode)
... corrective measure for error dispatches reaching here
subroutine errMessage(ierrCode)
integer :: ierrCode
write(*,*) ErrorMessage(i) ! break here
end subroutine errMessage
Jim Dempsey

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page