Silverfrost Forums

Welcome to our forums

Run-time bug

30 Sep 2017 8:23 #20340

I encountered what I believe to be an issue with run-time error checking and formatted reads.

Reading a floating point using the 'A' format specifier should yield a run-time error, or an error that can be 'trapped' at least.

The following code demonstrates this using both a floating point and a logical and reading with the 'A' format specifier. The floating point read works (and gives a weird value, but the logical will throw a run-time error.

    real abcd
    logical my_log
    character*32:: buffer='1234.5'
    abcd = 0.0
    my_log = .false.
    read(buffer,'(a)',err=2000,end=1000)abcd
    print *,abcd
    read(buffer,'(a)')my_log  ! this will cause the run time format/data mismatch error
    stop
2000	continue
	print *,'Error Detected'
    stop
1000	continue
	print *,'EOF Detected'
    stop
    end
30 Sep 2017 10:05 #20341

I don't think that the Fortran standard is of much use in guiding us as to what should happen, given that the code is non-conforming. This is not one of the few errors that a compiler is required to issue an error message for.

Most compilers, unless asked to check errors, will assume that the programmer has taken care to match format items and I/O list items regarding type. Specifically, the problem is that the A in the format string does not match a character type item in the I/O list, but is used to read a REAL. Thus, whether an error message is to be issued, etc., depends on how much error checking is done.

Regarding the 'weird' value of the REAL, here is the explanation. The data is read using the A format, resulting in placing the six characters into memory: '1', '2', '3', '4', '.', .5'. When you print the contents of abcd as a real, only four bytes are used, i.e., '1', '2.', '3', '4'. The hexadecimal representation of the real is thus Z'34333231'. Taking this as an IEEE-32 real gives us the value 1.6688934E-07, which is probably the 'weird' value that you mentioned.

You can see this yourself by using the output statement

write(*,'(1x,Z8)')abcd, transfer(buffer(:4),abcd)
2 Oct 2017 6:41 #20347

I have tested this code under Win32 and x64 and in both cases I get a runtime exception 'Format/data mismatch'. I don't think this feature has been added since the last full release but maybe it has.

P.S. Sorry I miss-read the post. I will note the omission.

18 Feb 2019 3:57 #23257

I have checked this and it turns out that FTN95 expressly permits this form.

Presumably it is sometimes used intentionally.

I note that gFortran also permits this.

18 Feb 2019 4:56 #23258

Isn't this some sort of hangover from the pre-CHARACTER days of Fortran-66? In those days you had to read character data into REAL or INTEGER variables. How many characters you got in depended on how big the variables were, and how many bits were used in the character set.

On a machine with 24-bit words, and 2 words per variable (REAL and INTEGER being the same length) then you might get 6 individual characters in each if they used an 8-bit code, or before that, when the original Fortran used a 6-bit character set (hence no lower case) you might get 8.

In my archives I still have (but don't use) code of the sort:

      DIMENSION TITLE(12)
      READ(5,100) TITLE
  100 FORMAT(12A6)

Obviously, the elements of TITLE don't contain sensible REAL numbers, but print them out with A formats and the original string will re-appear.

So, if you fed in 72 characters starting with 1234.5 ... and FORMAT(12A6), the TITLE(1) would contain ASCII codes 31 32 33 34 2E 35 in hex.

How this works with a generic A format is anyone's guess.

One needed to remember to write them out with a leading carriage-control character, as in:

      WRITE(6,200) TITLE
  200 FORMAT(1H0, 12A6)

The past is a foreign country: they do things differently there ...

Eddie

Please login to reply.