Why am I getting an error with list directed read?

The following produces an exception (runtime failure) in Intel Fortran (ifort, 2021.12.0, 32-bit, Windows 10, compiled in Visual Studio 2022):

program main
    character(6) :: foo
    integer :: stat_
    real :: x
    
    foo = '      '
    read(foo, *, iostat=stat_) x
    
    print *, 'x=', x, 'stat_=', stat_, 'foo=', foo
end program main

Here’s the error

forrtl: severe (24): end-of-file during read, unit -5, file Internal List-Directed Read

Oddly enough the error goes away if I change the * to '(F)', but then the status is also zero.

I was under the impression that if you include an iostat variable, that any errors are “trapped”. gfortran just sets stat_ to -1. Is Intel not being compliant here or am I missing something?

Which version of ifort are you using. ifort 2021.12.0 and ifx 2024.1.0 both give the expected result (iostat = -1) and no error message. You only get the error message if you remove the iostat=stat_. You must be using an older version of ifort. Also which OS are you using. Please include OS and compiler versions when you ask for help.

Edit

As to why you get an error in the first place. Unlike standard format specifiers, blanks are NOT considered zeros in list directed reads etc.
You are trying to read six blanks into a real value. I think Fortran see this as a record without an end of record mark or some other delimiter hence the error message. Note if you change

foo = '     '

to

foo = '     ,'

your program will run without error. I think adding the , will force Fortran to treat the values in foo as a null field (the same as doing a ,,). In this case the value of x is not changed from its initial value (which can be anything since you don’t give x an initial value before the read).

I’m using ifort 2021.12.0, 32-bit, Windows 10, Visual Studio 2022. Here are my compiler options (as shown by Visual Studio - I just created a new project and hit build):

/nologo /debug:full /Od /warn:interfaces /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc170.pdb" /traceback /check:bounds /check:stack /libs:dll /threads /dbglibs /c

Unlike standard format specifiers, blanks are NOT considered zeros in list directed reads etc.

This is good - I actually want a blank (all spaces) character variable to generate an error here. I just don’t want it to crash, just be able to detect it with the iostat.

The background here is an external application calls into the Fortran and passes in a large data structure with a bunch of numbers. Typically, when a number is 0 it means the user didn’t specify a value and a default or some record needs to be read instead, but this is a rare case where 0 is valid, so the program needs to distinguish whether the user input a value or not so it stores the number as a string. Not ideal, but there’s legacy.

This behavior was perplexing, so I tried the standalone program here and still got the same results.

For comparison, here is the test page for Compiler Explorer:

The site provides only up to ifort 2021.11.0, and the latter gives istat_=-1 (with no runtime error). So the issue might be related to some factors other than versions…? (e.g. 32 vs 64bit installation, or Windows-specific issue?) It might be useful to print the compiler version and options also as

program main
    use iso_fortran_env
    implicit none
    ...
    print *, "version =", compiler_version()
    print *, "options =", compiler_options()

The result for ifort 2021.11.0 (on the above site) is like this:

version =
 Intel(R) Fortran Intel(R) 64 Compiler Classic for applications
running on Intel (R) 64, Version 2021.11.0 Build 20231010_000000
 options =
 -g -o /app/output.s -gxx-name=/opt/compiler-explorer/gcc-13.2.0/bin/g++ -L./lib
  -Wl,-rpath,./lib -Wl,-rpath,/opt/compiler-explorer/intel-fortran-2024.0.0.4949
 3/compiler/latest/lib 

(Various versions/options for ifort / ifx / gfortran can be tested with the above site.)

This is what I’m seeing

Hi @adamyakes, thanks for trying the compiler_version() and options()!

At the moment, I guess the issue may be related to some specific combination (e.g., Windows I/O + ifort + possibly some environmental ones), but I have no more clue because I’ve never used Fortran on Windows… (only Linux and Mac).

Anyway, I think it may be useful to post a question also on the Intel Fortran forum
(if not yet done) by linking this Discourse page also for reference.

I have seen other bugs this reminds me of; sometimes where the bug was in the diagnostic code trying to report the error.

Since no one has been able to reproduce it – the previous bugs in various compilers were that a tab or other non-printable character was in the string and the error message for that error caused an internal error, whereas an error for hitting end-of-file did not; that the internal file had to be at least as many digits as huge(0), and that not returning iomsg as well as iostat caused an internal error when the message was going to output instead of a string. Since others cannot seem to reproduce the problem is it possible you have something like a tab in the string? It would not mean you have not found a bug, but it might explain why it is not reproducing easily.

Does this also hit the bug in your programming environment? If not, if you change CHS from 80 to 6 does it?

program main
integer,parameter   ::  chs=80
character(len=chs)  ::  foo
integer             ::  iostat
real                ::  x
character(len=255)  ::  iomsg=''

   foo = repeat(char(32),chs)
   read(foo, *, iostat=iostat,iomsg=iomsg) x

   print *, 'x=', x, 'iostat=', iostat, 'foo="'//trim(foo)//'" iomsg=',trim(iomsg)
end program main

if it fails the first time, if you change the format from list-directed to something like ‘(f6.6)’ does it work?