[comp.lang.fortran] record length for direct access files

mccalpin@perelandra.cms.udel.edu (John D. McCalpin) (09/24/90)

Silicon Graphics revised the behavior of their Fortran compiler for
direct access files in release 3.2 of their O/S to define the record
length (RECL=NNN) in words rather than bytes.  In explanation, the
release notes state:

	"The ANSI standard states that the specified record lengths
	 for unformatted direct access files must imply the number of
	 words."

Since I have observed a variety of behaviors for this particular
issue, I decided to look it up in the new standard.  

From the Fortran-90 draft S8, version 112, section 9.3.4.5, discussing
the RECL= parameter to the OPEN statment:

	"If the file is being connected for unformatted input/output,
	 the length is measured in processor-dependent units."

AAAAARRRRRRGGGGGGHHHHHH!

Is this in the current draft?  I can't believe that after all the
committee's mouthing about portability, they have let this one slip
through.  No, on second thought, I believe it entirely....

Not only do they give the vendors more license for incompatible
processor-dependent variability, but they skip the obvious fix of
giving us a SIZEOF() intrinsic function that would enable us to code
around the problem....

A quick survey:
	Silicon Graphics, Sun, Stardent all use RECL=words
	IBM RS/6000 uses RECL=bytes

Does anyone have a copy of the most recent draft to check on this?
--
John D. McCalpin			mccalpin@perelandra.cms.udel.edu
Assistant Professor			mccalpin@vax1.udel.edu
College of Marine Studies, U. Del.	J.MCCALPIN/OMNET

staff@cadlab.sublink.ORG (Alex Martelli) (09/25/90)

mccalpin@perelandra.cms.udel.edu (John D. McCalpin) writes:
	...
>Is this in the current draft?  I can't believe that after all the
>committee's mouthing about portability, they have let this one slip
>through.  No, on second thought, I believe it entirely....
	AAARGH!  It's really incredible, though believable... and it
	reinforces my impression that they were out to create a new,
	arguably beautiful language, rather than to actually help people
	who program in *FORTRAN*, for Pete's sake.

>Not only do they give the vendors more license for incompatible
	Not 'more', just as much as right now.  Still hateful, though.

>	Silicon Graphics, Sun, Stardent all use RECL=words
>	IBM RS/6000 uses RECL=bytes

Funny!  OUR Sun machines use RECL in bytes, as do HP, Olivetti, and
OS/2.  Dec and Sony use (long)words [do all MIPS boxes?].

-- 
Alex Martelli - CAD.LAB s.p.a., v. Stalingrado 45, Bologna, Italia
Email: (work:) staff@cadlab.sublink.org, (home:) alex@am.sublink.org
Phone: (work:) ++39 (51) 371099, (home:) ++39 (51) 250434; 
Fax: ++39 (51) 366964 (work only; any time of day or night).

sjc@key.COM (Steve Correll) (09/26/90)

In article <MCCALPIN.90Sep24090852@pereland.cms.udel.edu>, mccalpin@perelandra.cms.udel.edu (John D. McCalpin) writes:
| Silicon Graphics revised the behavior of their Fortran compiler for
| direct access files in release 3.2 of their O/S to define the record
| length (RECL=NNN) in words rather than bytes.  In explanation, the
| release notes state:
| 
| 	"The ANSI standard states that the specified record lengths
| 	 for unformatted direct access files must imply the number of
| 	 words."
| 
| Since I have observed a variety of behaviors for this particular
| issue, I decided to look it up in the new standard.  
| 
| From the Fortran-90 draft S8, version 112, section 9.3.4.5, discussing
| the RECL= parameter to the OPEN statment:
| 
| 	"If the file is being connected for unformatted input/output,
| 	 the length is measured in processor-dependent units."
| 
| AAAAARRRRRRGGGGGGHHHHHH!
| 
| Is this in the current draft?

The S8.115 (June 90) draft section 9.3.4.5 page 9-8 says "processor-dependent
units". But so does the X3.9-1978 (Fortran 77) standard page 12-26. The folks
at SGI should read more carefully.
 
If the committee prefers not to define a construct which Fortran 77 left
explicitly undefined, perhaps they could add a new RECSIZE= clause which is
defined to use the same units as a new SIZEOF intrinsic, and put RECL= in their
small typeface. They could still let the processor decide what those units are.
-- 
sjc@key.com or ...{sun,pyramid}!pacbell!key!sjc 		Steve Correll

khb@chiba.Eng.Sun.COM (Keith Bierman - SPD Advanced Languages) (09/26/90)

In article <MCCALPIN.90Sep24090852@pereland.cms.udel.edu> mccalpin@perelandra.cms.udel.edu (John D. McCalpin) writes:


   Silicon Graphics revised the behavior of their Fortran compiler for
   direct access files in release 3.2 of their O/S to define the record
   length (RECL=NNN) in words rather than bytes.  In explanation, the
   release notes state:

	   "The ANSI standard states that the specified record lengths
	    for unformatted direct access files must imply the number of
	    words."

This is untrue. Page 12-20 of X3.9-1978 clearly states

	...the length is measured in processor-dependent units...
...
   issue, I decided to look it up in the new standard.  

   From the Fortran-90 draft S8, version 112, section 9.3.4.5, discussing
   the RECL= parameter to the OPEN statment:

	   "If the file is being connected for unformatted input/output,
	    the length is measured in processor-dependent units."

Which is necessary to make f90 a superset of f77.

--
----------------------------------------------------------------
Keith H. Bierman    kbierman@Eng.Sun.COM | khb@chiba.Eng.Sun.COM
SMI 2550 Garcia 12-33			 | (415 336 2648)   
    Mountain View, CA 94043

mccalpin@perelandra.cms.udel.edu (John D. McCalpin) (09/26/90)

>>>>> On 25 Sep 90 07:16:34 GMT, staff@cadlab.sublink.ORG (Alex Martelli) said:

Alex> mccalpin@perelandra.cms.udel.edu (John D. McCalpin) writes:
>	Silicon Graphics, Sun, Stardent all use RECL=words
>	IBM RS/6000 uses RECL=bytes

Alex> Funny!  OUR Sun machines use RECL in bytes, as do HP, Olivetti, and
Alex> OS/2.  Dec and Sony use (long)words [do all MIPS boxes?].

Ooops, my brain got a bit scrambled there -- Sun does use RECL=bytes.
There are two separate issues that I have been working with:

	(1) RECL=words vs RECL=bytes
	(2) control words in unformatted sequential files

To be specific:

(1)	Machine			RECL=bytes	RECL=words
	--------------------------------------------------
	Silicon Graphics 3.1	    X
	Silicon Graphics 3.2+			    X
	Sun 4.0			    X
	Stardent				    X
	IBM RS/6000		    X
	--------------------------------------------------

(2)	Machine			  C-W=bytes	C-W=words
	--------------------------------------------------
	Silicon Graphics 3.1	    X
	Silicon Graphics 3.2+	    X
	Sun 4.0			    X
	Stardent				    X
	IBM RS/6000		    X
	--------------------------------------------------
	The control word is a 32-bit integer written before
	and after each FORTRAN unformatted sequential record
	which specifies its length.  It is not normally visible
	to the user (from FORTRAN).

The fact that Sun, SGI, and IBM all use IEEE and control-word=bytes
means that I can read the same FORTRAN unformatted sequential access
files transparently on any of those machines.  Since they use
different RECL conventions however, the *source* requires
proprocessing to be portable.  How about that --- binary portability
but *not* source portability!

A simple C program can convert the Stardent files to the more common
format, but it would be much nicer if we could convince Stardent to
change a few lines of code in their FORTRAN I/O libraries to provide
this compatibility. (Any Stardent users out there?)

--
John D. McCalpin			mccalpin@perelandra.cms.udel.edu
Assistant Professor			mccalpin@vax1.udel.edu
College of Marine Studies, U. Del.	J.MCCALPIN/OMNET

maine@elxsi.dfrf.nasa.gov (Richard Maine) (09/26/90)

In article <MCCALPIN.90Sep24090852@pereland.cms.udel.edu>, mccalpin@perelandra.cms.udel.edu (John D. McCalpin) writes:
John> Silicon Graphics revised the behavior of their Fortran compiler for
John> direct access files in release 3.2 of their O/S to define the record
John> length (RECL=NNN) in words rather than bytes.  In explanation, the
John> release notes state:
John> 
John> 	"The ANSI standard states that the specified record lengths
John> 	 for unformatted direct access files must imply the number of
John> 	 words."
John> 
John> Since I have observed a variety of behaviors for this particular
John> issue, I decided to look it up in the new standard.  
John> 
John> From the Fortran-90 draft S8, version 112, section 9.3.4.5, discussing
John> the RECL= parameter to the OPEN statment:
John> 
John> 	"If the file is being connected for unformatted input/output,
John> 	 the length is measured in processor-dependent units."
John> 
John> AAAAARRRRRRGGGGGGHHHHHH!
John> 
John> Is this in the current draft?

On 25 Sep 90 18:10:44 GMT, sjc@key.COM (Steve Correll) said:

Steve> The S8.115 (June 90) draft section 9.3.4.5 page 9-8 says
Steve> "processor-dependent units". But so does the X3.9-1978 (Fortran
Steve> 77) standard page 12-26. The folks at SGI should read more
Steve> carefully.

Yep.  Sounds to me like the SGI folk meant the "ANSI standard" in the
sense that if that's the way the Vax compiler works, it must be
standard.  :-)

Actually, I'd think the Vax way would be a poor choice for a Unix
environment where there is no need to restrict the record length
to necessarily being a multiple of the "word" length.  But that's
one of those quality of implementation issues; the standard clearly
allows either choice.

Steve> If the committee prefers not to define a construct which
Steve> Fortran 77 left explicitly undefined, perhaps they could add a
Steve> new RECSIZE= clause which is defined to use the same units as a
Steve> new SIZEOF intrinsic, and put RECL= in their small typeface.
Steve> They could still let the processor decide what those units are.

See the IOLENGTH specifier in the INQUIRE statement.  Section 9.6.3
in the S8.115 draft.  A little on the awkward side for my taste, but
it does achieve the desired purpose.  The result from the IOLENGTH
specifier is defined to be suitable for RECL.  Sample use:

      type my_type
         ...lots of obscure stuff
      end type

      type(my_type) :: my_variable

      integer :: record_length, iostat

      !--- And another variable to throw in, just to clarify that
      !--- we can have a general io-list, not restricted to a single item.
      integer :: key

      ....

      inquire(iolength=record_length) key, my_variable
      open (10,file='myfile',form='unformatted', &
           access='direct', recl=record_length, &
           status='new',action='readwrite',iostat=iostat)
      if (iostat /= 0) ....whatever...

      write(10,rec=1,iostat=iostat) key, my_variable
      ....

--

Richard Maine
maine@elxsi.dfrf.nasa.gov [130.134.64.6]

rff@inf.rl.ac.uk (Ronald Fowler) (09/27/90)

In article <MCCALPIN.90Sep26090619@pereland.cms.udel.edu> mccalpin@perelandra.cms.udel.edu (John D. McCalpin) writes:
>There are two separate issues that I have been working with:
>
>	(1) RECL=words vs RECL=bytes
>	(2) control words in unformatted sequential files
>
And goes on to say that Stardent has RECL=words and (control words)=words.

Since Stardent is a recent merger, I wouldn't be surprised if they have
two "standards", since on our machine (a GS2000, was a Stellar) we seem
to have RECL=bytes and (control words)=bytes.

hirchert@harriett.ncsa.uiuc.edu (Kurt Hirchert) (10/02/90)

In article <MCCALPIN.90Sep24090852@pereland.cms.udel.edu> mccalpin@perelandra.cms.udel.edu (John D. McCalpin) writes:
>Silicon Graphics revised the behavior of their Fortran compiler for
>direct access files in release 3.2 of their O/S to define the record
>length (RECL=NNN) in words rather than bytes.  In explanation, the
>release notes state:
>
>	"The ANSI standard states that the specified record lengths
>	 for unformatted direct access files must imply the number of
>	 words."
>
>Since I have observed a variety of behaviors for this particular
>issue, I decided to look it up in the new standard.  
>
>From the Fortran-90 draft S8, version 112, section 9.3.4.5, discussing
>the RECL= parameter to the OPEN statment:
>
>	"If the file is being connected for unformatted input/output,
>	 the length is measured in processor-dependent units."
>
>AAAAARRRRRRGGGGGGHHHHHH!
>
>Is this in the current draft?  I can't believe that after all the
>committee's mouthing about portability, they have let this one slip
>through.  No, on second thought, I believe it entirely....
>
>Not only do they give the vendors more license for incompatible
>processor-dependent variability, but they skip the obvious fix of
>giving us a SIZEOF() intrinsic function that would enable us to code
>around the problem....

As several other people have already pointed out, SGI is wrong!  FORTRAN 77
specifies the use of processor-dependent units.  In practice, this means
either bytes or words, but in theory it could mean bits or pages.

Fortran 90 also uses processor-dependent units for at least two reasons:
o  Forcing a particular unit (e.g., bytes) would "break" many existing programs
   (e.g., those written on systems that currently use words).
o  Choosing a particular unit might interfere with future extension.  (E.g.,
   choosing bytes as the i/o unit might be less than appropriate on a machine
   that could control record lengths in units of bits.)

Fortran 90 skipped the "obvious" fix of a SIZEOF() intrinsic function because
the "obvious" fix doesn't always work.  In particular, the size of a record is
_not_ always the sum of the sizes of its components.  Even worse, the sum of
the sizes of the components wasn't even a bound on the size of the record; we
were able to identify both cases of a record needing to be larger than the
sum of the sizes of its components (due to issues such as alignment) and cases
of a record being smaller than the sum of the sizes of its components (due to
partial unit reuse/overlap).

Instead, Fortran 90 offered the capability to use the INQUIRE statement to
determine the size of complete records.  If you are writing only one kind of
record, you can simply feed the result of the INQUIRE back into an OPEN.  If
you are writing more than one kind of record, you can inquire on each and
pass on the maximum.  Really ambitious programmers could attempt restructuring
records in order to produce sets of records that are the same size (or nearly
so) in order to optimize disk usage.  (You can also deduce SIZEOF() type
information on machines where that model holds, but remember that this may
limit your portability.)
--
Kurt W. Hirchert     hirchert@ncsa.uiuc.edu
National Center for Supercomputing Applications

sjc@key.COM (Steve Correll) (10/02/90)

I may or may not have posted a half-finished message on this subject (postnews
somehow grabbed the wrong file, placed it in our /usr/spool/news directory, and
then gave me a "no message posted" message). Here's a more concise version,
with errors corrected. Please ignore the first one if you got it, and accept my
apology for whatever it was I did wrong:
=======================================

Thanks for bringing INQUIRE/IOLENGTH to my attention. I have a couple of
questions for Fortran 90 experts:

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)

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?

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)

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.

(Incidentally, a less perverse example which _is_ computable at compilation
time, but not trivially so, is the following, which writes a triangular portion
of a matrix. Any guesses on how many Fortran 90 compilers will get this stuff
wrong the first time out?)

	dimension x(5000, 5000)
	inquire(iolength=il) ((x(i, j), i=1, j), j=1, 5000)
	...
	write(unit=io) ((x(i, j), i=1, j), j=1, 5000)

-- 
sjc@key.com or ...{sun,pyramid}!pacbell!key!sjc 		Steve Correll

maine@elxsi.dfrf.nasa.gov (Richard Maine) (10/02/90)

On 1 Oct 90 23:50:19 GMT, sjc@key.COM (Steve Correll) said:

Steve> Thanks for bringing INQUIRE/IOLENGTH to my attention. I have a couple of
Steve> questions for Fortran 90 experts:

I'm not sure I qualify as an "expert".  The number of Fortran 90
programs that I have gotten to compile to date seems a little low
to justify the term. :-)  But I'll give the questions a try anyway.

Steve> 1. Is there anything in the Fortran 90 standard which forbids
Steve> the following?  (The intent is to write an element-count "icnt"
Steve> followed by that number of elements of an array).

Steve> 	... (part omitted)
Steve> 	read *, icnt
Steve> 	inquire(iolength=record_length) icnt, (x(j), j=1, icnt)
Steve>  ... (etc)

Steve> 2. If that example is legal, then I believe it's not possible
Steve> to compute at compilation time how long the records will
Steve> actually be. Is it intended that the INQUIRE/IOLENGTH construct
Steve> be computed at execution time rather than at compilation time?

Looks legal to me, and I agree with your conclusion that it's not
required to be computed at execution time.  I can't find anything
in the standard that requires that.  (That doesn't *guarantee* that
it isn't there, but I can't find it).

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?
Steve>   
Steve> 	inquire(iolength=record_length) icnt, (x(j), j=1, icnt)
Steve> 	open(unit=ii, file='myfile', form='unformatted', &
Steve> 	  access='direct', recl=record_length, &
Steve> 	  status='old', action='readwrite', iostat=iostat)
Steve> 	read(unit=ii) icnt, (x(j), j=1, icnt)

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.

Basically, the above example "has to" be illegal because it otherwise
would imply that you could read 2 different records with 2 different
lengths from the same direct access file in the same open; just add a
second read, which specifies rec=2.  That is pretty explicitly
illegal.  (Oh yes, I just noticed you left the rec= specifier out
above; that's illegal, but I assume that was just an accidental
omission and not the point you were asking about).

--

Richard Maine
maine@elxsi.dfrf.nasa.gov [130.134.64.6]

hirchert@harriett.ncsa.uiuc.edu (Kurt Hirchert) (10/03/90)

In article <2152@key.COM> sjc@key.COM (Steve Correll) writes:
>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)

The example looks OK to me.
>
>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?

Perhaps "intended" is too strong a word.  There is no intent to discourage
compile-time evaluation of INQUIRE(IOLENGTH= ), but it was recognized that
this will not always be possible.
>
>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)

It depends on how literally I am to take your example.  As written, icnt is
undefined, so this constitutes a reference to an undefined variable.
>
>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.

It's all a question of what you consider "the same input/output list".  As a
practical matter in this example, the value of record_length returned for any
particular value of icnt will be sufficient to hold records corresponding to
using that icnt _or_a_smaller_one_ in the read and write statements.

To put it another way, INQUIRE(IOLENGTH= ) is a tool for portably determining
record lengths, not a panacea to banish all possible problems in this area.
The limitations inherent in a fixed record size remain.
>
>(Incidentally, a less perverse example which _is_ computable at compilation
>time, but not trivially so, is the following, which writes a triangular portion
>of a matrix. Any guesses on how many Fortran 90 compilers will get this stuff
>wrong the first time out?)
>
>	dimension x(5000, 5000)
>	inquire(iolength=il) ((x(i, j), i=1, j), j=1, 5000)
>	...
>	write(unit=io) ((x(i, j), i=1, j), j=1, 5000)

My guess would be that many compilers will simply punt and do it at execution
time.  On the other hand, won't compilers have to deal with similar constructs
in DATA statements?  (My /S8.115 isn't handy, so I can't check this myself
right now.)  If they can get it right in the DATA statement, why should they
get it wrong in the INQUIRE?
--
Kurt W. Hirchert     hirchert@ncsa.uiuc.edu
National Center for Supercomputing Applications

bill@ssd.csd.harris.com (Bill Leonard) (10/04/90)

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

bill@ssd.csd.harris.com (Bill Leonard) (10/04/90)

In article <MAINE.90Oct2095538@altair.dfrf.nasa.gov> maine@elxsi.dfrf.nasa.gov (Richard Maine) writes:

   Basically, the above example "has to" be illegal because it otherwise
   would imply that you could read 2 different records with 2 different
   lengths from the same direct access file in the same open; just add a
   second read, which specifies rec=2.  That is pretty explicitly
   illegal.

I'm sorry, Richard, but this isn't illegal at all.  The standard does not
guarantee you _can_ do it, but it doesn't forbid an implementation from
allowing it.  (See previous posting in answer to Steve Correll for more
detail.)
--
Bill Leonard
Harris Computer Systems Division
2101 W. Cypress Creek Road
Fort Lauderdale, FL  33309
bill@ssd.csd.harris.com

burley@world.std.com (James C Burley) (10/05/90)

In article <1990Oct3.160641.19506@ux1.cso.uiuc.edu> hirchert@harriett.ncsa.uiuc.edu (Kurt Hirchert) writes:

   >	dimension x(5000, 5000)
   >	inquire(iolength=il) ((x(i, j), i=1, j), j=1, 5000)
   >	...
   >	write(unit=io) ((x(i, j), i=1, j), j=1, 5000)

   My guess would be that many compilers will simply punt and do it at execution
   time.  On the other hand, won't compilers have to deal with similar constructs
   in DATA statements?  (My /S8.115 isn't handy, so I can't check this myself
   right now.)  If they can get it right in the DATA statement, why should they
   get it wrong in the INQUIRE?
   --
   Kurt W. Hirchert     hirchert@ncsa.uiuc.edu
   National Center for Supercomputing Applications

Well, in a DATA statement

    data ((x(i,j), i=1,j), j=1,5000)

the compiler "executes" the statement requiring that it know the values for
i and j each time it evalutes x(i,j).  I.e. replace 5000 with a variable and
the inquire statement may still be valid, but the data statement is not.

However, a compiler may be smart enough to see that an implied-DO construct
has constant values for the iterations (1,5000) or the nonconstant values
are safely dependent on enclosing implied do construct's iterators (safe in
that the iterators aren't changed via something like equivalence) and, in the
case of inquire, do some nifty but relatively easy analysis to determine if
the case can be made compile-time instead of run-time.  Even if it had to
"execute" the construct at compile time, which might be somewhat slow since
it wouldn't be in compiled form (it'd be like interpreting from an AST or
expression tree), it'd be better to do it then instead of at run time in
most cases, I imagine (cross-compiling on an IBM PC XT to run on a Cray Y-MP
might be an exception :-).

Further, in the case of inquire involving a variable limit, it might even
be smart enough to bypass the repeated invocation of the "here's another value
to inquire-iolength about" and instead simply compute how many calls WOULD
be made, as an expression, and pass that expression to a "how big would N of
these values be?"

For example:

    inquire(iolength=foo) ((x(i,j),i=1,k),j=1,n)

Instead of generating "output_real(x(i,j))" n*k times and then asking "how
long was the mythical record?", it could just generate "calc_n_reals(n*k)"
and then ask -- or if the answer is known by the compiler in addition to the
run-time library, just calculate it directly: "foo=n*k*4" (assuming 4 bytes
per real, for example).  I don't have my math brain on to figure out how
it would handle a triangular case (replace "k" with "j" in the above
example), but I suspect it there could still be found a straightforward
replacement computation.

I'd like to get all sorts of neat things into GNU Fortran someday, but for
now I'd be happy to get an alpha release out...still carving gargoyles for
the moment!  Sigh....

James Craig Burley, Software Craftsperson    burley@world.std.com