- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The SUBROUTINE get_unit of the popular iso_varying_string.f95 module, uses the following line:
read(unit=unit, FMT="(A)", ADVANCE="NO", &
IOSTAT=iostat, SIZE=n_chars_read) buffer(:n_chars_read)
If an EOF is reached, apparently n_chars_read is not specified, and the subroutine produces unexpected results.
Apparently, gfortran assigns n_chars_read=0, so the subroutine works.
I'm not sure what the standard says about this, but it's something that ifort programmers should be aware of.
read(unit=unit, FMT="(A)", ADVANCE="NO", &
IOSTAT=iostat, SIZE=n_chars_read) buffer(:n_chars_read)
If an EOF is reached, apparently n_chars_read is not specified, and the subroutine produces unexpected results.
Apparently, gfortran assigns n_chars_read=0, so the subroutine works.
I'm not sure what the standard says about this, but it's something that ifort programmers should be aware of.
Link Copied
11 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The code you show seems to assume that the SIZE= value is set before the length of the data transfer is established. The standard says this is not the case. According to 9.5.3 (Execution of a data transfer input/output statement), definition of the SIZE= variable is the very last thing to happen before the END=, ERR=, EOR= or IOSTAT is processed.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
buffer(:n_chars_read) determines the entity that receives the data, which occurs in item 6 of 9.5.3:
(6) Transfer data between the file and the entities specified by the input/output list (if any) or
namelist.
Later, item 9 in 9.5.3 says:
(9) Cause any variable specified in a SIZE= specifier to become defined.
Thus, it has to be defined. I would assume that if and EOF occured, then nothing was read and the variable specified in a SIZE= should be set to zero.
The variable n_chars_read is assigned by the READ statement after buffer(:n_chars_read) is processed.
The code might be confusing because n_chars_read shows up twice, but it could be a different variable.
(6) Transfer data between the file and the entities specified by the input/output list (if any) or
namelist.
Later, item 9 in 9.5.3 says:
(9) Cause any variable specified in a SIZE= specifier to become defined.
Thus, it has to be defined. I would assume that if and EOF occured, then nothing was read and the variable specified in a SIZE= should be set to zero.
The variable n_chars_read is assigned by the READ statement after buffer(:n_chars_read) is processed.
The code might be confusing because n_chars_read shows up twice, but it could be a different variable.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't understand what you wrote in the last post. Perhaps you could show a small but complete program that demonstrates the issue?
The single source line you posted implies to me that the author believes that the SIZE value is set before the I/O list is processed, but the standard has it the other way around. Perhaps you don't understand "standard speak". Here, "become defined" means "has a value stored into it".
The single source line you posted implies to me that the author believes that the SIZE value is set before the I/O list is processed, but the standard has it the other way around. Perhaps you don't understand "standard speak". Here, "become defined" means "has a value stored into it".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Let's make it simpler. My initial point was this:
Compiling with ifort 11.1, the following line will not store a value into n_chars_read when an EOF occurs (i.e. iostat = -1):
read(unit=unit, FMT="(A)", ADVANCE="NO", IOSTAT=iostat, SIZE=n_chars_read) buffer
n_chars_read becomes defined on step 9 of 9.5.3 and this step should not be skipped even if an EOF occured, in which case the value 0 (zero) should be stored into n_chars_read.
Note that I removed (:n_chars_read) from buffer(:n_chars_read) because that was leading to a different discussion.
Compiling with ifort 11.1, the following line will not store a value into n_chars_read when an EOF occurs (i.e. iostat = -1):
read(unit=unit, FMT="(A)", ADVANCE="NO", IOSTAT=iostat, SIZE=n_chars_read) buffer
n_chars_read becomes defined on step 9 of 9.5.3 and this step should not be skipped even if an EOF occured, in which case the value 0 (zero) should be stored into n_chars_read.
Note that I removed (:n_chars_read) from buffer(:n_chars_read) because that was leading to a different discussion.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ok, I get it now. This appears to be a problem only if one is positioned at the end of file before doing the READ. If you simply read up to and past the end of the record, the SIZE value is ok. I'll report this to the developers. Issue ID is DPD200158604.
I still think the code you posted originally is wrong.
I still think the code you posted originally is wrong.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Right. OK. Thank you.
What about this code:
INTEGER, PARAMETER :: unit = 10
INTEGER :: dummy, n_chars_read, iostat
CHARACTER(LEN=256) :: buffer
n_chars_read = 5
dummy = n_chars_read
read(unit=unit, FMT="(A)", ADVANCE="NO", IOSTAT=iostat, SIZE=n_chars_read) buffer(1:dummy)
From my point of view the original code and this one should do the same.
What about this code:
INTEGER, PARAMETER :: unit = 10
INTEGER :: dummy, n_chars_read, iostat
CHARACTER(LEN=256) :: buffer
n_chars_read = 5
dummy = n_chars_read
read(unit=unit, FMT="(A)", ADVANCE="NO", IOSTAT=iostat, SIZE=n_chars_read) buffer(1:dummy)
From my point of view the original code and this one should do the same.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, that code and the original have the same meaning. But I don't think that's what the author of the first code intended.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve --
In fact, I *did* mean what I wrote in the first code. But it looks fishy, unless you see the context; n_chars_read is set by an earlier statement as the number of characters to read, and is then overwritten after the read statement has completed with the number of characters actually read.
cheers,
Rich
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As an addendum, it seems like this problem has come up before:
Still no fix?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Looks like I missed recognizing that there was a bug from that earlier post. Sorry about that.
And thanks for the clarification - as I noted above, it wasn't entirely clear from the single source line what was intended.
And thanks for the clarification - as I noted above, it wasn't entirely clear from the single source line what was intended.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Fixed in version 12.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page