Silverfrost Forums

Welcome to our forums

Format bug

8 Oct 2015 8:17 #16896

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
8 Oct 2015 10:58 #16897

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 specifi ed or implied width using the E, EN, ES, D, or G edit descriptor, or the number of characters produced exceeds the fi eld width, the processor shall fill the entire fi eld of width w with asterisks.

9 Oct 2015 12:18 #16898

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?

9 Oct 2015 2:11 #16899

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

9 Oct 2015 5:22 #16901

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 😃

9 Oct 2015 7:14 #16902

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?

9 Oct 2015 11:23 #16903

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

9 Oct 2015 2:18 #16904

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.

9 Oct 2015 4:03 #16905

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?

9 Oct 2015 5:25 #16906

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.

9 Oct 2015 7:31 #16907

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?

10 Oct 2015 7:09 #16908

Yes, naturally the subroutine would provide a toggle. After that users can use the routine or not depending on how useful they find it.

11 Oct 2015 12:49 #16911

Paul,

That should solve Dan's problem; a bit like handling tab characters for formatted reads ( see READ_TABS@ with OPEN )

John

11 Oct 2015 7:19 #16912

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.

11 Oct 2015 7:34 #16913

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.

12 Oct 2015 10:01 #16915

I'd look also how IVF treats that.

12 Oct 2015 10:42 #16916

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.

12 Oct 2015 8:56 #16920

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

13 Oct 2015 2:16 #16921

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:

  1. If ERR and IOSTAT are absent, the program terminates if there is an IO error

  2. If ERR is present the program jumps to the line label regardless of the error

  3. 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.

13 Oct 2015 3:31 #16923

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:

  1. An error is not an error if you don't check for it.
  2. You cannot compare IOSTAT to zero to decide whether an error occurred.
  3. ... many other inconsistencies that will be revealed only after extensive investigation and/or experience.
Please login to reply.