A bug? Should go to 999, isn't it ?
i=10
write(*,'(i1)',err=999) i
Print*, 'Goes here if this is compiler bug'
Stop
999 Print*, 'Goes here if there is no compiler bug'
end
Welcome to our forums
A bug? Should go to 999, isn't it ?
i=10
write(*,'(i1)',err=999) i
Print*, 'Goes here if this is compiler bug'
Stop
999 Print*, 'Goes here if there is no compiler bug'
end
No bug here, not in the compiler.
If you had checked the output produced by the WRITE, you would have received a clue to what happened, which is specified by the Fortran standard as follows On output, if an exponent exceeds its specified or implied width using the E, EN, ES, D, or G edit descriptor, or the number of characters produced exceeds the field width, the processor shall fill the entire field of width w with asterisks.
Let it fill the whole field with the asterisks or other garbage but what we see in the output shows some kind of conflict and for sure has to have the means for programmer to be managed. So i instructed compiler that in case of problem redirect the output to 999. it did not react. If Standard things that this is normal the Standard must be changed because this is obviously not. Though i'd be happy if Silverfrost just made an extension
And what means 'If you had checked the output produced by the WRITE' ? ROTFL. Having bad day again?
Dan,
What is included as a reported error condition has always been debated. Numeric overflow for the available field is explicitly discussed in the standard and a non-error condition response is provided.
If you want a different response, then you need to code for it, using out of range testing.
There are lots of problems with what is or is not an error condition, where an err= or iostat= response should be expected. (are they listed in the standard ?)
When using F77, I had coded an internal 'read (string,fmt='(i10)',iostat=ii) num' to test if string contained a valid integer. This all worked well with many compilers until I transferred the code to an IBM compiler and the program crashed with an undetected error. I found that what was an expected error detection condition was up to the compiler developer. One of the many failings of the F77 standard, which I blamed on IBM.
I am also worried by the problem when using FTN95 business format, using B'ZZZ,ZZZ,ZZ#' instead of B'---,---,--#' if reporting -ve values. Should using B'ZZZ,ZZZ,ZZ#' be an error ?
John
Nothing to debate here, John. The code
i=10
write(*,'(i1)') i
should produce on output what it produces right now, the asterisks, the stars or whatever. While if err=999 is explicitly used
i=10
write(*,'(i1)',err=999) i
the code should be directing its execution where programmer wants it to. Why the heck i wrote err=999? To be ignored? That is the dumbest absurd of Standard committee.
I just lost two days with such error produced by C. And my colleagues spent a month before having no idea what sometimes happening with the code. The huge files ~10 GB can be contaminated with few NAN numbers somewhere in the middle so that it was impossible even to look inside, and even if you look you will not spot them. Following the design ideology of this compiler with its strictest checking of everything it should not follow BS other compilers do and if user is concerned do not allow the behavior like we discuss above.
This compiler made so many extensions to the Fortran Standard that adding one million more will not even be noticed 😃
I think that jumping to the alternate return could be useful and probably fairly easy to implement. At the same time it could be unwelcome in some user's existing code.
The relevant FTN95 library code is in the DLL - i.e. a runtime issue, so it would be tricky to provide an FTN95 command line switch for this feature. However, we might be able to use an environment variable for this purpose. Another way would be provide a subroutine call to switch this feature on.
Any thoughts?
Dan, The action of the print statement whereby asterisks are printed for an overflow is the saviour of every Fortran programmer and just a sign that their format need widening. It is not an error. Please Paul, do not change it!
A simple work-around.
character*1 result
i=10
write(result,'(i1)') i
if(result .eq. '*')then
Print*, 'Goes here if there is an overflow'
else
Print*, 'Goes here if there is not an overflow'
endif
Print *,result
end
or
i=10
if(abs(I>9)then
Print*, 'Goes here if there is an overflow'
else
Print*, 'Goes here if there is not an overflow'
endif
Print '(i1)',i
end
Ian
My suggestion does not break any valid code, Paul and Ian. There could be done few workarounds of course. My suggestion is very logical and very simple: if user wrote err=label then in case of error it must be granted not ignored.
/* Some though like the Ian's first one could make loading or writing of my 10 of 10GB files painfully longer. Welcome to the 64 bit world where i/o speed and error checking needs better quality.
Quoted from DanRRight My suggestion does not break any valid code, Paul and Ian.
Not true. If a WRITE were done to a field that was not sufficiently wide, and such a WRITE should activate an ERR= clause if that clause is present, as you want, the program would need to be terminated when no ERR= or IOSTAT= clause is present, because 9.11.2-2 of the Fortran 2008 standard says If an error condition occurs during execution of an input/output statement that contains neither an ERR= nor IOSTAT= specifier, error termination of the program is initiated. IanLambley's first program, for instance, would have to be terminated at the WRITE statement.
For your suggestion to work without breaking valid code, the WRITE would have to cause an error state to be entered only when an ERR= clause is present. In other words, it should be an error only if you check for an error (with the ERR=clause).
Paul, even if it appears simple to change SALFLIBC.DLL to make writing to an insufficient field width an error, it would require much care and effort to shield users from such nonstandard behavior. Consider a specific example: I write code that uses DanRRight's library code. I expect standard behavior, the DRR library code requires non-standard behavior, and both segments of code may do formatted I/O. Will SALFLIBC.DLL support both behaviors simultaneously? This is an instance where setting an environmental variable would not work. If you required a dedicated subroutine call to initiate the nonstandard behavior, on the other hand, different problems arise. Will I then have to make a second dedicated subroutine call in my code to restore standard behavior, after control returns to my code following a call to the DRR library?
Perhaps I have not stated my suggestion clearly.
I am offering to provide a user callable FTN95 library routine such that, only when it is called, you will get the behaviour that Dan is asking for. So nothing changes unless and until this new routine is called somewhere before the related print statements.
Quoted from PaulLaidler Perhaps I have not stated my suggestion clearly.
I am offering to provide a user callable FTN95 library routine such that, only when it is called, you will get the behaviour that Dan is asking for. So nothing changes unless and until this new routine is called somewhere before the related print statements.
I understand that, but my concern is as follows: once the to-be-provided subroutine in SALFLIBC is called, the behavior gets changed irrevocably.
It should be possible to revert to present behavior as desired; in other words, that subroutine call should be a toggle.
There is another thorny issue that will have to be dealt with. If you accept an ERR= clause, you will probably also have to accept an IOSTAT= clause, and decide upon a set of IOSTAT values to identify different types of errors (some of which are not errors according to the Fortran standard). Without a full set of IOSTAT values, merely reaching the target statement number of ERR= will probably not enable recovery from the error.
For instance, in Dan's example, WRITE(,'(I1)',ERR=100)I, what would happen with I=-1? What if the format string and the I/O list contained mismatches? For example, WRITE(,'(I1)', ERR=100)STR, where STR is a character variable?
Yes, naturally the subroutine would provide a toggle. After that users can use the routine or not depending on how useful they find it.
Paul,
That should solve Dan's problem; a bit like handling tab characters for formatted reads ( see READ_TABS@ with OPEN )
John
Paul, Will this need to be turned on and off because in some few cases the above response may be required. In other cases the normal response may be required. Perhaps there should be an option to automatically turn off the feature after it has responded as Dan requires. Switch it on only before the statement where it is needed and automatically turn off after the statement has executed. Ian.
OK. I am thinking that we could have a general routine to configure the I/O with a flag for each option. One option would be equivalent to READ_TABS@ etc.
I'd look also how IVF treats that.
Intel Fortran has IOSTAT=63 condition, which relates to this problem, although I have never seen it occur. I am not sure how it would work, or how to select between 'error or info' The following is an extract taken from Intel's List of Run-Time Error Messages. https://software.intel.com/en-us/node/525375
63 error or info(63): Output conversion error
FOR$IOS_OUTCONERR. During a formatted output operation, the value of a particular number could not be output in the specified field length without loss of significant digits. When this situation is encountered, the overflowed field is filled with asterisks to indicate the error in the output record. If no ERR address has been defined for this error, the program continues after the error message is displayed. To suppress this error message, see the description of check[:]nooutput_conversion.
Note: The severity depends on the check[:]keywords option used during the compilation command. The ERR transfer is taken after completion of the I/O statement for error numbers 61, 63, 64, and 68. The resulting file status and record position are the same as if no error had occurred. However, other I/O errors take the ERR transfer as soon as the error is detected, so file status and record position are undefined.
Anyone has IVF to run the code on message 1? The Silverfrost developers simply MUST have it.
But let's return to this issue after /64 will be ready, it is of 1/10000000 the importance
I think John's suggestion of setting an IOSTAT condition for this problem would be favourite. To me it seems important that the compiler should behave in a consistent manner as follows:
If ERR and IOSTAT are absent, the program terminates if there is an IO error
If ERR is present the program jumps to the line label regardless of the error
If IOSTAT is present the program continues regardless and the programmer decides what if anything to do.
So if we define WRITE (*,'(I1)') 10 as an error then the program should stop in case 1 above. I think that this is undesirable. If it is agreed that it is undesirable to stop in case 1, then case 2 should not apply either (which is as things stand and the reason for the original post). Instead setting a non-zero IOSTAT value seems the only logical option. The non-zero value could then be interpreted not as an actual error, but as a form of information that output has not proceeded in a simple manner. FTN95 currently returns IOSTAT=0.
Simon,
It is good to see someone think through the ramifications of a suggested change to the compiler. In the present instance, Paul has made it clear that the extension, which is not in conformity with the standard, will apply only when it is chosen through a deliberate subroutine call. As long as most users are shielded from such non-standard behavior, one cannot complain about its being provided, apart from observing that I as a user would rather see Silverfrost direct its development efforts to issues that relate to unimplemented features of the standard (such as those in TR-15581), 64 bit code, etc.
I see this problem with your description in Item 2.: If ERR is present the program jumps to the line label regardless of the error. The very abbreviation ERR implies association with an error, and the standard itself says the following in 9.11.5 regarding IOSTAT:
1 Execution of an input/output statement containing the IOSTAT= specifier causes the scalar-int-variable in the IOSTAT= specifier to become defined with a zero value if neither an error condition, an end-of-file condition, nor an end-of-record condition occurs,...
Thus, we are faced with a number of inconsistencies when the proposed non-standard extension is active: