[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#369547: This bug seems to be fixed in gfortran 4.1.x



Hi!

The issue you are experiencing seems to be due to record-marker length
lack of interoperability.

In brief, AIUI, the problem is that Fortran standard specifications do
not mandate any low level form for unformatted file I/O.
Hence every compiler adopts its own form and *no* unformatted file
interoperability is guaranteed between different Fortran compilers.

Many compilers (including g77 <= 3.3 and ifort) have adopted the
following low level structure for an unformatted record:

  START_MARK  DATA   END_MARK

where START_MARK and END_MARK are two identical 32 bit signed integers
that represent the record length (in bytes) and DATA is the actual
record payload.
In your case, START_MARK and END_MARK are the 32 bit signed integer
representation of 12 (since your three integers make 12 bytes).
This approach sets the maximum length of writeable/readable unformatted
records to (2^31 - 1) bytes. To go beyond this limit some compilers
exploit various backward-compatible techniques (based on the
record-marker sign bit).
Another way to go beyond this limit is using 64 bit signed integers as
record-markers.
This sets the limit to (2^63 - 1) bytes, which is fairly much more...
This is the strategy adopted by g77 >= 3.4 and gfortran, which is
unfortunately not backward-compatible, though...
In your case, START_MARK and END_MARK are the 64 bit signed integer
representation of 12, which is a 32 bit signed representation of 12
followed by a 32 bit signed representation of zero (remember that you
are on i386, which is a little-endian architecture).
When you read the file with a program which thinks that record-markers
are 32 bit long, the second half of START_MARK is interpreted as if it
were the first integer (hence i=0), then the first two actual integers
are read (j=1 k=2) and the rest is ignored.


OK, this should explain what happened (at least I hope so...).
Now some news:

This bug (lack of interoperability) seems to be fixed by upstream in
gfortran 4.1.x (see  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19303 
for details).

I began to write a little C++ program to convert between different
Fortran unformatted record-markers.
I have a preliminary version that seems to work on little-endian
machines (with little endian Fortran unformatted files): I can attach it
if someone is interested.
License is GNU GPL v2 only (the project got rejected by Savannah since I
don't want to license it under any later version of the GNU GPL: see
http://savannah.gnu.org/task/?func=detailitem&item_id=5204  if you're
interested in all the gory licensing details).


HTH.

-- 
    :-(   This Universe is buggy! Where's the Creator's BTS?   ;-)
......................................................................
  Francesco Poli                             GnuPG Key ID = DD6DFCF4
 Key fingerprint = C979 F34B 27CE 5CD8 DC12  31B5 78F4 279B DD6D FCF4

Attachment: pgpVhUkU2ZavB.pgp
Description: PGP signature


Reply to: