[comp.lang.fortran] Bug with file I/O?

quan@sol.surv.utas.edu.au (Stephen Quan) (01/24/91)

I ran the following on our SunOS machine, and guess what the output is?

------>start of test.f<------
      program test
      integer     buff(1)
      character*4 tmp
      equivalence (tmp,buff)

1     format (a4)

      open (10,file='test.dat',access='direct',recl=8,form='formatted')
      buff(1) = 10
      write (10,1,rec=1) tmp
      buff(1) = 0
      read  (10,1,rec=1) tmp
      write (*,*) buff(1)
      close (10)

      end
------>end of test.f<------

What is the last value of buff(1)?  10?  0? ... NO, 32!!  I need the result
to be 10, can anybody tell me what I am doing wrong?  For those who followed
the thread "Array Dilemma", this problem is related to implementing BIG.
This time, I am working on some big integers.
--
Stephen Quan,
University of Tasmania.

system@alchemy.chem.utoronto.ca (System Admin (Mike Peterson)) (01/24/91)

In article <quan.664695995@sol> quan@sol.surv.utas.edu.au (Stephen Quan) writes:
>I ran the following on our SunOS machine, and guess what the output is?
>     <test program deleted>
>What is the last value of buff(1)?  10?  0? ... NO, 32!!  I need the result
>to be 10, can anybody tell me what I am doing wrong?

Our Apollo (SR10.2 / ftn 10.7) gives '10' for this program.
Looks like a broken compiler to me. Have you tried dumping the
'test.dat' file (with 'od') to see if it is the write or the read that
is messing up? As an aside, why not use binary/unformatted direct I/O;
it is orders of magnitude faster than formatted I/O on all systems I
have ever used?
-- 
Mike Peterson, System Administrator, U/Toronto Department of Chemistry
E-mail: system@alchemy.chem.utoronto.ca
Tel: (416) 978-7094                  Fax: (416) 978-8775

khb@chiba.Eng.Sun.COM (chiba) (01/25/91)

In article <quan.664695995@sol> quan@sol.surv.utas.edu.au (Stephen Quan) writes:


   I ran the following on our SunOS machine, and guess what the output is?
...

f77 quan.f && a.out
quan.f:
 MAIN test:
  10
chiba:/net/chiba/home2/khb>


This is with the "current" version of the compiler, viz. the one
released last year. f77v1.3.1.

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

bill@hcx2.ssd.csd.harris.com (Bill Leonard) (01/25/91)

In article <1991Jan24.145718.28686@alchemy.chem.utoronto.ca>, system@alchemy.chem.utoronto.ca (System Admin (Mike Peterson)) writes:
> Our Apollo (SR10.2 / ftn 10.7) gives '10' for this program.
> Looks like a broken compiler to me. Have you tried dumping the
> 'test.dat' file (with 'od') to see if it is the write or the read that
> is messing up? As an aside, why not use binary/unformatted direct I/O;
> it is orders of magnitude faster than formatted I/O on all systems I
> have ever used?

Beware!  Unformatted I/O is not guaranteed to work if you mix data types.
Writing an INTEGER and reading a CHARACTER may give unpredictable results.

In any case, you cannot say the original compiler is broken, because this
program is non-standard.  Using an A edit descriptor with non-character
data is non-standard and non-portable.  Unless the user's manual
specifically says it is supposed to work and specifically says you can mix
this with character data, you probably can't.

-- 
Bill Leonard
Harris Computer Systems Division
2101 W. Cypress Creek Road
Fort Lauderdale, FL  33309
bill@ssd.csd.harris.com
---------------------------------------------------------------------------
I have yet to see any problem, however complicated, which, when looked
at in the right way, did not become still more complicated.
                -- Poul Anderson
---------------------------------------------------------------------------

mkh6317@rigel.tamu.edu (HOWARD, MATTHEW KENDALL) (01/25/91)

In article <2136@travis.csd.harris.com>, bill@hcx2.ssd.csd.harris.com (Bill Leonard) writes...
> 
>In any case, you cannot say the original compiler is broken, because this
>program is non-standard.  Using an A edit descriptor with non-character
>data is non-standard and non-portable.  Unless the user's manual
>specifically says it is supposed to work and specifically says you can mix
>this with character data, you probably can't.
> 
Bill,

You might want to look at the program again.  There is nothing non-
standard about it.  The A descriptor is only used on the variable
tmp which is typed as character.

Matt

3003jalp@ucsbuxa.ucsb.edu (Applied Magnetics) (01/25/91)

In article <11495@helios.TAMU.EDU> mkh6317@rigel.tamu.edu (HOWARD, MATTHEW KENDALL) writes:

>[...]
>You might want to look at the program again.  There is nothing non-
>standard about it.

Yes there is.  It equivalences character data to an integer.  Should
still work, though.  Stephen, check the fine print in your compiler
manual.  You never know.

  --Pierre Asselin, R&D, Applied Magnetics Corp.  I speak for me.

calvin@dinkum.wpd.sgi.com (Calvin H. Vu) (01/25/91)

In <quan.664695995@sol> quan@sol.surv.utas.edu.au (Stephen Quan) writes:

| I ran the following on our SunOS machine, and guess what the output is?
| 
| ------>start of test.f<------
|       program test
|       integer     buff(1)
|       character*4 tmp
|       equivalence (tmp,buff)
| 
| 1     format (a4)
| 
|       open (10,file='test.dat',access='direct',recl=8,form='formatted')
|       buff(1) = 10
|       write (10,1,rec=1) tmp
|       buff(1) = 0
|       read  (10,1,rec=1) tmp
|       write (*,*) buff(1)
|       close (10)
| 
|       end
| ------>end of test.f<------
| --
	The problem is that you are trying to write binary data to a 
    formatted file.   UNIX I/O library assumes that all data written
    to a formatted file are "readable" characters and hence uses <CR>
    which happens to be the number you are using to determine record
    boundary.

    The scenario is:

    You write out 4 bytes: \0 \0 \0 <CR>
    and then read it back in. Since the I/O library interprets the <CR>
    as the record terminator it only reads in 3 bytes \0 \0 \0.  And
    since your READ statement requested for 4 bytes it substitute the
    missing data byte with 32 (i.e. blank character) which is appropriate
    for the A4 format.  So you have the number 32.

	You can probably do a similar tricks without having to equivalence
    'buff' to 'tmp'.  Writing 'buff' using A4 format gives a similar bad
    result.   Ditto for FORM='formatted' without ACCESS='direct'.

	On SGI system we have FORM='binary' to do exactly this type of
    unorthodox programming, i.e. writing binary "unreadable" data to a
    formatted file.

	If you are using direct access file, I don't see why you should not
    use unformatted file instead of formatted.  It probably makes the I/O
    faster and your record 1 byte shorter (i.e. no <CR> appended).

    On the other hand, MAYBE this can qualify as a bug since
    you may argue that the record boundary for a direct-access record should
    be determined by the record length (or the last <CR> in that record)
    and not the first <CR> the I/O library runs into.

| Stephen Quan,
| University of Tasmania.
--
-----------------------------------------------------------------------------
Calvin H. Vu			   | "We are each of us angels with only one
Silicon Graphics Computer Systems  | wing.  And we can only fly embracing
calvin@sgi.com   (415) 962-3679	   | each other."

quan@sol.surv.utas.oz (Stephen Quan) (01/25/91)

3003jalp@ucsbuxa.ucsb.edu (Applied Magnetics) writes:

>In article <11495@helios.TAMU.EDU> mkh6317@rigel.tamu.edu (HOWARD, MATTHEW KENDALL) writes:

>>[...]
>>You might want to look at the program again.  There is nothing non-
>>standard about it.

>Yes there is.  It equivalences character data to an integer.  Should
>still work, though.  Stephen, check the fine print in your compiler
>manual.  You never know.

>  --Pierre Asselin, R&D, Applied Magnetics Corp.  I speak for me.

For those who wanted to know, I was running it on a Sparc 1, SunOS 4.0.3c,
but I wouldn't have a clue what version our compiler is, all I can say is
it is not the most recent version.

In summary :
1. od of my file is :
   0000000  000000 000012 000000 000000
   0000010
   so no problems about writing.

2. reading it back in the string produces 32 not 10.
   presumably formatted I/O interpreted 10 as a newline, and padded
   string with spaces.

3. works on some machines Apollo, IBM VS-Fortran and latest versions of
   Sun / Fortran combinations (from email responses).

4. 'unformatted' seems to be the general consensus for the solution, to
   which I am happily using :).

5. (Why?)  The reason why I wanted this, was, I needed an economical
   way of storing integers and accessing them from a file.  The program
   will be ultimately ported to a PC.  Any other method of storage,
   apart the character storage will not be as ecomical, especially when
   I need about 150000 of them!

Thanks to all who responded.

Stephen Quan,
University of Tasmania,
Australia.

khb@chiba.Eng.Sun.COM (chiba) (01/25/91)

In article <quan.664762832@sol> quan@sol.surv.utas.oz (Stephen Quan) writes:



   For those who wanted to know, I was running it on a Sparc 1, SunOS 4.0.3c,
   but I wouldn't have a clue what version our compiler is, all I can say is
   it is not the most recent version.

for "modern" compiler releases the verbose command has been augmented
(-v still does just what it used to):

f77 -V quan.f
version-id of "/home2/lang/SC0.0/SC0.0/f77pass1":    SC0.0	f77 1.3.1 FCS	90/06/25
/home2/lang/SC0.0/SC0.0/f77pass1 "-P -cg87" quan.f /tmp/f77pass1.24751.s.0.s /tmp/f77pass1.24751.i.1.s /tmp/f77pass1.24751.d.2.s
quan.f:
 MAIN test:
version-id of "/home2/lang/SC0.0/SC0.0/as":          SC0.0		90/02/12
...

for old (and certainly obsolete) versions

cat /usr/lib/lang_info

As documented on page 1 of the RTF (at least the last version of the
compiler which supported this scheme, v1.2, put it there). I've long
since trashed my personal docs from before then.

For doing real C style I/O (streams, etc.) one might want to shield
the application from the details, and have one small machine dependent
bit of code...
--
----------------------------------------------------------------
Keith H. Bierman    kbierman@Eng.Sun.COM | khb@chiba.Eng.Sun.COM
SMI 2550 Garcia 12-33			 | (415 336 2648)   
    Mountain View, CA 94043

erwin@suncvt12.verfahrenstechnik.uni-stuttgart.de (Dieterich Erwin) (01/25/91)

I tried to mail the following, but the mail bounced back...


In article <quan.664695995@sol> you write:
>I ran the following on our SunOS machine, and guess what the output is?
>
>------>start of test.f<------
>  program deleted
>------>end of test.f<------
>
>What is the last value of buff(1)?  10?  0? ... NO, 32!!  I need the result
>to be 10, can anybody tell me what I am doing wrong?  For those who followed
>the thread "Array Dilemma", this problem is related to implementing BIG.
>This time, I am working on some big integers.
>--
>Stephen Quan,
>University of Tasmania.


Well, it worked on my SUN:

   Hallo> make test
   f77   -sun4 -o test test.f
   test.f:
    MAIN test:
   Hallo> test
     10

I don't know what went wrong on your computer. I have a Sparc 1+ with
SunOS 4.1 and FORTRAN v1.3 running.

  Sorry that I can't help you better.

		erwin

system@alchemy.chem.utoronto.ca (System Admin (Mike Peterson)) (01/29/91)

In article <2136@travis.csd.harris.com> bill@hcx2.ssd.csd.harris.com (Bill Leonard) writes:
>In article <1991Jan24.145718.28686@alchemy.chem.utoronto.ca>, system@alchemy.chem.utoronto.ca (System Admin (Mike Peterson)) writes:
>> 	 As an aside, why not use binary/unformatted direct I/O;
>> it is orders of magnitude faster than formatted I/O on all systems I
>> have ever used?
>
>Beware!  Unformatted I/O is not guaranteed to work if you mix data types.
>Writing an INTEGER and reading a CHARACTER may give unpredictable results.

I would not have just converted the program given to not use a FORMAT,
I would also make it read/write only integers to the direct access file.
While using A format on integers "works" on most systems, I wouldn't
recommend it either, and mixing data types between the write and the
read in unformatted I/O is almost a sure trip to disaster as Bill points out.
-- 
Mike Peterson, System Administrator, U/Toronto Department of Chemistry
E-mail: system@alchemy.chem.utoronto.ca
Tel: (416) 978-7094                  Fax: (416) 978-8775