Path: utzoo!attcan!uunet!wuarchive!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!uflorida!travis!bill From: bill@ssd.csd.harris.com (Bill Leonard) Newsgroups: comp.lang.fortran Subject: Re: record length for direct access files (corrected) Message-ID: Date: 3 Oct 90 17:39:02 GMT References: <2146@key.COM> <2151@key.COM> <2152@key.COM> Sender: news@travis.csd.harris.com Organization: Harris Computer Systems Division Lines: 130 In-reply-to: sjc@key.COM's message of 1 Oct 90 23:50:19 GMT In article <2152@key.COM> sjc@key.COM (Steve Correll) writes: Thanks for bringing INQUIRE/IOLENGTH to my attention. I have a couple of questions for Fortran 90 experts: First, my credentials: member of X3J3 (for 3 years) and member of the Control Structions and I/O technical subgroup (the one responsible for the applicable sections of the draft standard). 1. Is there anything in the Fortran 90 standard which forbids the following? (The intent is to write an element-count "icnt" followed by that number of elements of an array). dimension x(5000) integer record_length ... read *, icnt inquire(iolength=record_length) icnt, (x(j), j=1, icnt) open(unit=io, file='myfile', form='unformatted', & access='direct', recl=record_length, & status='new', action='readwrite') write(unit=io,rec=1) icnt, (x(j), j=1, icnt) close(unit=io) No, this is perfectly legal; in fact, it is an example of precisely how we envision this being used. 2. If that example is legal, then I believe it's not possible to compute at compilation time how long the records will actually be. Is it intended that the INQUIRE/IOLENGTH construct be computed at execution time rather than at compilation time? There is no need for requiring compile-time evaluation. The RECL= specifier's value does not have to be constant. It's value is not used in deciding the size of any storage requirements, but rather the size of records in the file (which pretty much has to be execution-time decidable, else it would be useless). 3. Now suppose another program wants to read the file back in. Is there anything in the Fortran 90 standard that forbids the following example? inquire(iolength=record_length) icnt, (x(j), j=1, icnt) open(unit=ii, file='myfile', form='unformatted', & access='direct', recl=record_length, & status='old', action='readwrite', iostat=iostat) read(unit=ii) icnt, (x(j), j=1, icnt) The value if ICNT must be defined at the time the INQUIRE statement is executed. Remember that INQUIRE is not reading anything, so it doesn't define ICNT. Since you use ICNT in the implied-DO loop on the INQUIRE statement, it must have a value. Next, let me explain what the RECL= means on your OPEN statement here, at least as far as the standard is concerned. Since you specified an existing file (STATUS='OLD'), the standard says "the value of the RECL= specifier must be included in the set of allowed record lengths for the file". The standard (even F77) allows (but does not require) an implementation to provide direct-access files with varying record lengths, if it desires to. It might allow the records to be any length, or it might allow only a finite, user-specified, set of lengths that records are allowed to be. In your example, what your OPEN statement says to the system is "I want to access this file using direct access, and I expect to read and/or write records of length record_length". The system may reject your OPEN (i.e., return an error) if that particular file cannot support that record length. (Of course, there are whole host of other possible errors the system may detect. I notice you don't check IOSTAT after the OPEN -- naughty, naughty! :-) The most important lesson from this little discussion is that the RECL= value specified on an OPEN for reading _DOES NOT GUARANTEE_ that all the records in the file are that specific length. All it guarantees is that the file can handle records of that length. In short, if you use the same value of ICNT when you open for reading that you used when you created the file, your example should work (barring other errors on the OPEN). Note that, if the record you read was produced using the same I/O list as the READ used, then the READ will obtain the correct number of values (since it first reads the value of ICNT to get the number of array elements to read). (Assuming ICNT does not exceed the bounds of the array. :-) 4. If that example is legal, then is the compiler allowed to give the "wrong" answer by using the value of "icnt" at the time of the INQUIRE/IOLENGTH statement even though that value will change during the READ statement? S8.115 section 9.6.3 says INQUIRE/IOLENGTH computes a suitable record length for "input/output statements with the same input/output list", as if it were always possible to do so correctly. When the standard says "the same input/output list", it means _effectively_ the same. That is, with exactly the same values in all the corresponding variables. Changing the names of the variables does not change the results of the INQUIRE. Changing the _values_ of those variables (possibly even the values in the array!) _is_ allowed to change those results. For instance, the following two statements must produce the same value for RECORD_LEN: INQUIRE(IOLENGTH=RECORD_LEN) (X(I), I=1,3) INQUIRE(IOLENGTH=RECORD_LEN) X(1), X(2), X(3) On 1 Oct 90 23:50:19 GMT, sjc@key.COM (Steve Correll) said: > Steve> 3. Now suppose another program wants to read the file back in. > Steve> Is there anything in the Fortran 90 standard that forbids the > Steve> following example? > Yes, at least the way I read it. The standard says that the iolist in > the inquire is an output list and that it gives the value that would > result from the use of the same output list in an unformatted output > statement. Admittedly, it then procedes to mention input/output lists > and statements. I'm not at all sure that 2 such identical appearing > i/o lists would count as the "same list" if the values of icnt were > different. Doesn't seem like they "reasonably" should, but I haven't > spent much time contemplating the precise semantics of the wording > used in the standard in that area. No, they don't count as the same list if ICNT is different. However, I'll try to clear up the confusion over "output list" versus "input/output list". The length of a record in the file is determined when it is written, not when it is read. The set of allowed record lengths for a file is determined when it is created (using the RECL= value on the OPEN and possibly additional information). Therefore, if you created the file using the INQUIRE by IOLENGTH, you can use the _same_ INQUIRE statement to compute the value you should specify on the OPEN. Clear? :-) -- Bill Leonard Harris Computer Systems Division 2101 W. Cypress Creek Road Fort Lauderdale, FL 33309 bill@ssd.csd.harris.com