- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have a general reading routine that crashes for empty files (ASCII).
The following minimal example shows this behavior (compile; touch empty.txt; ./out) when compiled with ifort version 19.0.2.187. Is that the expected behavior, i.e. would I need to check for fileLength/=0 or is ifort suppost to figure this out.
program test character(len=:), allocatable :: a a = IO_read('empty.txt') print*, len(a) print*, '#'//a//'#' contains function IO_read(fileName) result(fileContent) character(len=*), intent(in) :: fileName character(len=:), allocatable :: fileContent integer :: & fileLength, & fileUnit, & myStat inquire(file = fileName, size=fileLength) open(newunit=fileUnit, file=fileName, access='stream',& status='old', position='rewind', action='read',iostat=myStat) if(myStat /= 0) stop 1 allocate(character(len=fileLength)::fileContent) read(fileUnit) fileContent close(fileUnit) end function IO_read end program test
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here's my analysis of the situation...
The READ is attempting to read zero bytes from an empty file connected for unformatted stream access. The standard says that an end-of-file condition occurs when "an attempt is made to read beyond the end of a stream file." Since the READ is not trying to read beyond the end of the file, the file position should remain unchanged and the READ should succeed.
Therefore, I believe this is an error on the part of ifort and should be reported to Intel using the Online Service Center.
Link Copied
- « Previous
-
- 1
- 2
- Next »
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That's interesting, and another bug. Let me do some tests on that.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Why not simply respond to " inquire(file = fileName, size=fileLength)" for empty (size=0) or non-existent (size=-1), without opening the file.
Perhaps use if ( fileLength <= 0) then ; allocate(character(len=0)::fileContent) ; else ; ...
Isn't fileLength = -1 already a problem ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
John Campbell wrote:Why not simply respond to " inquire(file = fileName, size=fileLength)" for empty (size=0) or non-existent (size=-1), without opening the file.
Perhaps use if ( fileLength <= 0) then ; allocate(character(len=0)::fileContent) ; else ; ...
The first solution leaves fileContent unallocated which requires further checks in other parts of the code (the MWE given here is not the full code).
A non-existing file is certainly a problem, but I sometimes have optional files and simply check whether they exist (with inquire)
In general, I prefer to write code without special cases.
Unfortunately, the use of modern Fortran reveals often compiler glitches (not just in Intel products) that require to use a non-optimal solution. Hence, when in doubt I try to clarify whether my code is invalid or whether the compiler does not respect the standard.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I can't reproduce the iostat comparison issue you mentioned in post 21. The iostat properly comes back as -1 and comparing /= 0 works.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Steve,
many thanks for your investigations. Actually, I think my explanation was a little bit misleading.
- If I read a file of length N, N>0, into a string of length N, the iostat return value is 0. Hence, I assume an error for iostat /= 0 (error: iostat > 0, read beyond EOF: iostat = -1).
- If I read a file of length 0 into a sting of length 0, the iostat return value is -1. This seems to be a contradiction to your statement from the standard which states that -1 is returned if "an attempt is made to read beyond the end of a stream file." According to my understanding, reading 0 bytes from a 0 bytes file should also result in iostat = 0 because EOL was not reached (file length matches length of read). Due to this unexpected behavior, I need to change my code to accept an iostat of -1, even though this signals that I tried to read more information than present in the file
Finally, just for the sake of completeness (I understand that you have confirmed that already): If the iostat argument for the read statement is missing I get an segmentation fault if reading a 0 length file. This behavior is cured if iostat is present as an actual argument
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It would be better to use the variable with the IOSTAT_END parameter of the intrinsic module ISO_FORTRAN_ENV, or the IS_IOSTAT_END function.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
andrew_4619 wrote:It would be better to use the variable with the IOSTAT_END parameter of the intrinsic module ISO_FORTRAN_ENV, or the IS_IOSTAT_END function.
many thanks, I did not know about this. Much easier to read
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Diehl, Martin wrote:
- If I read a file of length 0 into a sting of length 0, the iostat return value is -1. This seems to be a contradiction to your statement from the standard which states that -1 is returned if "an attempt is made to read beyond the end of a stream file." According to my understanding, reading 0 bytes from a 0 bytes file should also result in iostat = 0 because EOL was not reached (file length matches length of read). Due to this unexpected behavior, I need to change my code to accept an iostat of -1, even though this signals that I tried to read more information than present in the file
Right - that's a bug. You should be getting iostat=0 for reading zero bytes as you are not attempting to read past the end of file.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>You should be getting iostat=0 for reading zero bytes as you are not attempting to read past the end of file.
What is supposed to happen when you issue this 0-byte read, as the next read following a >0 byte read that returned EOF (-1)?
IOW the internal state is "read beyond end of file". This may present a different behavior should the file be opened for shared use or for exclusive use.
Martin, had your test program (legitimately) encountered an EOF return... then issued the 0-byte read?
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If the READ does not attempt to transfer data, it should not get an EOF condition, no matter where it is in a file connected for stream access. It is different for non-stream access.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove (Blackbelt) wrote:Martin, had your test program (legitimately) encountered an EOF return... then issued the 0-byte read?
No, the file is just opened (as in the example given in my initial post)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Intel informs me that this bug was fixed in the latest compiler release (compiler 2021.5.0, oneAPI HPC Toolkit 2022.1.) I had to argue a bit with the developers on this one, as they initially claimed the behavior was appropriate... I verified that the correct behavior is now seen.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- « Previous
-
- 1
- 2
- Next »