Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

None Advancing I/O and the t edit descriptor

29 views
Skip to first unread message

Ian Bush

unread,
Feb 14, 2012, 8:43:44 AM2/14/12
to

Hi all,

Different compilers are giving me different output for the following


Wot now? cat qwe.f90
Program tab

Write( *, '( t25 )', Advance = 'No' )
Write( *, '( "Hello" )' )

End Program tab

There's two schools. Firstly

Wot now? nagfor --version
NAG Fortran Compiler Release 5.2(721)
Option warning: Unrecognised option --version passed to loader
gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Wot now? nagfor qwe.f90
NAG Fortran Compiler Release 5.2(721)
[NAG Fortran Compiler normal termination]
Wot now? ./a.out
Hello
Wot now? ifort --version
ifort (IFORT) 12.0.4 20110427
Copyright (C) 1985-2011 Intel Corporation. All rights reserved.

Wot now? ifort qwe.f90
Wot now? ./a.out
Hello
Wot now? g95 --version
G95 (GCC 4.0.3 (g95 0.92!) Jun 24 2009)
Copyright (C) 2002-2008 Free Software Foundation, Inc.

G95 comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of G95
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING
Wot now? g95 qwe.f90
Wot now? ./a.out
Hello
Wot now? ~/ekopath-4.0.10/bin/pathf90 --version
PathScale (tm) Compiler Suite: Version 4.0.10
Built on:
Thread model: posix
GNU gcc version (PathScale 4.0.10 driver)

Copyright PathScale Inc and others. All Rights Reserved.
You can find complete copyright, patent and legal notices in the
corresponding documentation.
Wot now? ~/ekopath-4.0.10/bin/pathf90 qwe.f90
Wot now? ./a.out
Hello
Wot now? ~/Downloads/open64-4.2.4/bin/openf90 --version
Open64 Compiler Suite: Version 4.2.4
Built on: 2011-04-01 13:02:16 +0800
Thread model: posix
GNU gcc version 4.2.0 (Open64 4.2.4 driver)
Wot now? ~/Downloads/open64-4.2.4/bin/openf90 qwe.f90
Wot now? ./a.out
Hello



And then there's the second school
Wot now? gfortran --version
GNU Fortran (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
Copyright (C) 2010 Free Software Foundation, Inc.

GNU Fortran comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of GNU Fortran
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING

Wot now? gfortran -W -Wall -pedantic -std=f95 qwe.f90
Wot now? ./a.out
Hello
Wot now? f90 -V
f90: Sun Fortran 95 8.5 Linux_i386 2010/08/13
usage: f90 [ options ] files. Use 'f90 -flags' for details
Wot now? f90 qwe.f90
Wot now? ./a.out
Hello


I know there's some subtleties which non-Advancing I/O, are both of
these outputs possible,

Ian

Richard Maine

unread,
Feb 14, 2012, 11:35:04 AM2/14/12
to
Ian Bush <pleas...@email.me> wrote:

> Hi all,
>
> Different compilers are giving me different output for the following
>
>
> Wot now? cat qwe.f90
> Program tab
>
> Write( *, '( t25 )', Advance = 'No' )
> Write( *, '( "Hello" )' )
>
> End Program tab
>
> There's two schools. Firstly
[for a bunch of compilers]
> Wot now? ./a.out
> Hello
...
> And then there's the second school
...
> Wot now? ./a.out
> Hello

Hmm. I'm still a bit bleary-eyed, so my recollection of that kind of
detail might be a bit off, but I'm slightly surprised that so many
compilers put the blanks in. I'd swear that was just wrong and that the
"second school" was correct. But I'm having trouble finding the words in
the standard to definitively support this, so I'll not stand on it.

In 10.7.1 (of f2003), we have

"On output, a T, TL, TR, or X edit descriptor does not by itself cause
characters to be transmitted and therefore does not by itself affect the
length of the record."

Based on that, I tend to think of those edit descriptors as not having
any effect unless there is another edit descriptor after them. But I'm
not finding the words to put it all together. In particular, I can't
find the term "character position" defined at all. There is "file
position", and one might gess that "character position" might be the
same thing, but relative to the start of the current record, but I can't
find it definitively stated. This makes me unsure what it means when
10.7.1.1 says "Immediately prior to nonchild data transfer, the left tab
limit becomes defined as the character position of the current
record...".

That's because I can't tell for sure whether T changes the character
position. It changes "the position at which the next character wilbe
transmitted to or from the record", but is that the "character position"
or not? Too many undefined terms running around here. Or maybe I'm just
not finding them without some caffeine.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain

Dick Hendrickson

unread,
Feb 14, 2012, 12:01:38 PM2/14/12
to
I think that only the version with 25 leading blanks is correct. The
start of the tab section in f2003 says

"The T, TL, TR, and X edit descriptors specify the position at which the
next character will be transmitted to or from the record."

And, since non-advancing I/O doesn't go to the next record, it looks
like the T positioning should hold. I didn't see any qualifiers
exceptions in the section for non-advancing I/O.

There was an interpretation about Tabbing and next-records many years
ago; but I think it was related to the wording for what the new left-tab
position was.

Finally, what really convinced me was the NAG compiler output. As a
rule of thumb, never bet against Malcolm on a Fortran question! ;)

There's an interesting posting effect here. When I look at the original
message with thunderbird, most of the "hello"s are spaced in 25 spaces.
Only the SUN and gfortran ones begin in column 1. But, when I look at
the copy above, everything starts in column 1. Beats me.

Dick Hendrickson

Dick Hendrickson

unread,
Feb 14, 2012, 12:03:55 PM2/14/12
to
Darn, I see I just violated my other rule, never bet against Richard on
a Fortran question! ;)

Dick Hendrickson

Richard Maine

unread,
Feb 14, 2012, 12:09:06 PM2/14/12
to
Dick Hendrickson <dick.hen...@att.net> wrote:

> Darn, I see I just violated my other rule, never bet against Richard on
> a Fortran question! ;)

Yeah, well I'm not sure I'd bet "with myself" on this one. I also
noticed the bit that you quoted and it pulled me in the same direction
that you mentioned. So I'm not sure. Just too much trouble with terms
whose definitions I can't find.

Bob Stryk

unread,
Feb 14, 2012, 12:43:34 PM2/14/12
to
When I look at the first dozen lines of your quote of the original
message I see that the quote has been reformatted to eliminate leading
spaces. Contrasting with this is the quotes provided in Richard Maine's
messages which preserve the leading spaces.

Micki

unread,
Feb 14, 2012, 5:03:45 PM2/14/12
to
On Feb 14, 8:35 am, nos...@see.signature (Richard Maine) wrote:
>
> Based on that, I tend to think of those edit descriptors as not having
> any effect unless there is another edit descriptor after them.

But the words you quoted don't support "not having any effect", they
support "having the effect of lengthening the record not now but later
when subsequent characters are transmitted". Which amounts to
nothing if no subsequent characters are transmitted.

--Micki St. James

Richard Maine

unread,
Feb 14, 2012, 5:53:51 PM2/14/12
to
Well, I was certainly being sloppy in my wording, but my "unless there
is another edit descriptor after them" was meant to imply basically
that, insomuch as subsquent characters would have to be transmitted in
accordance with subsequent edit descriptors. I do agree my wording was
imprecise.

Ron Shepard

unread,
Feb 15, 2012, 1:45:30 AM2/15/12
to
In article <jhdoev$35a$1...@dont-email.me>,
Ian Bush <pleas...@email.me> wrote:

> Program tab
>
> Write( *, '( t25 )', Advance = 'No' )
> Write( *, '( "Hello" )' )
>
> End Program tab
>
> There's two schools. Firstly

This is related to the issue of whether T edit descriptors place
trailing spaces in output lines. I think the correct rule is that
they don't. For example

write(*,'("Hello World",T25)')

should simply write "Hello World" with no trailing spaces to the
output.

The first write statement above is (I think) covered by this same
rule. Nothing is written by the write statement, so the T25 is not
required to place any trailing spaces in the output. The
advance='no' complicates the situation, so I will let Richard and
others clarify that part of the issue.

If you do want to have 25 spaces, followed by something later in the
program on that same output record, then I think you need to write a
specific space at the end.

write(*,'(T24," ")',advance='no')

should work everywhere the same. There are other ways to achieve
this, of course, but this is one that uses the T edit descriptor.

There is also an issue with T edit descriptors in subsequent write
statements. I think the rule is that a later T5, for example, does
*NOT* refer to the 5th character of the output record, but rather
the 5th character of that local section of the output record. In
other words, a T1 in a subsequent write statement does not cause the
new output to overwrite what was already written on that output
record. It might have been nice if this were the case (e.g. to
print out a running progress counter in-place), but that is not the
way it works.

$.02 -Ron Shepard

Tobias Burnus

unread,
Feb 15, 2012, 2:42:47 AM2/15/12
to
Dick Hendrickson <dick.hen...@att.net> wrote:
>> Different compilers are giving me different output for the following
>>
>> Write( *, '( t25 )', Advance = 'No' )
>> Write( *, '( "Hello" )' )
>
> I think that only the version with 25 leading blanks is correct.
[...]
> There was an interpretation about Tabbing and next-records many years
> ago; but I think it was related to the wording for what the new left-tab
> position was.

I have asked at the J3 mailing list and got a reply by Bob Corbett of Sun
(now Oracle). He believes that the interpretation request (which he filled)
is about this issue and that having 25 blanks is correct. There is a pending
bug report for Oracle Solaris Studio Fortran; he had hoped to fix it for
12.3 but ran out of time.

Lacking a convincing argument that column 1 is the correct one, I follow
the crowd by believing that column 25 is correct. For GCC/gfortran, that's
tracked as problem report (PR) 52251.

The interpretation request is:
000027 "Sequential formatted I/O: position of the left tab"
at http://j3-fortran.org/doc/year/02/02-006c2.txt

The crucial sentence (according to DISCUSSION) is:
"Immediately prior to data transfer, the left tab limit becomes defined as
the character position of the current record."


> Finally, what really convinced me was the NAG compiler output. As a
> rule of thumb, never bet against Malcolm on a Fortran question! ;)

Well, I see a difference between the NAG compiler and the Malcolm answers.
While the NAG compiler is one of the better ones with regards to standard
compliance, compiler bugs - especially for corner cases - can never be ruled
out. (And I have already encountered some.)

Tobias

Richard Maine

unread,
Feb 15, 2012, 2:56:21 AM2/15/12
to
Tobias Burnus <bur...@net-b.de> wrote:

> The crucial sentence (according to DISCUSSION) is:
> "Immediately prior to data transfer, the left tab limit becomes defined as
> the character position of the current record."

Now if only I could find a definition of "the character position of the
current record."

Ian Bush

unread,
Feb 15, 2012, 3:58:16 AM2/15/12
to
On 14/02/12 13:43, Ian Bush wrote:
>
> Hi all,
>
> Different compilers are giving me different output for the following
>
>
> Wot now? cat qwe.f90
> Program tab
>
> Write( *, '( t25 )', Advance = 'No' )
> Write( *, '( "Hello" )' )
>
> End Program tab
>

Just to say thanks to all for your answers. I had hoped that school 1
would be what was supposed to happen, so I'm also happy with the outcome!

Ian

Erik Toussaint

unread,
Feb 15, 2012, 9:04:03 PM2/15/12
to
I hesitate to argue with the professionals and experts on such a
technical matter, but I've been reading through the standard and I can't
really find an airtight explanation of the process; it seems to me to
allow some room for interpretation, so regard this as nothing more than
my attempt at making sense of things.


On 15-2-2012 8:42, Tobias Burnus wrote:
> Dick Hendrickson<dick.hen...@att.net> wrote:
>>> Different compilers are giving me different output for the following
>>>
>>> Write( *, '( t25 )', Advance = 'No' )
>>> Write( *, '( "Hello" )' )
>>
>> I think that only the version with 25 leading blanks is correct.

25 blanks or 24 blanks and "Hello" starting at position 25?


> [...]
>> There was an interpretation about Tabbing and next-records many years
>> ago; but I think it was related to the wording for what the new left-tab
>> position was.
>
> I have asked at the J3 mailing list and got a reply by Bob Corbett of Sun
> (now Oracle). He believes that the interpretation request (which he filled)
> is about this issue and that having 25 blanks is correct. There is a pending
> bug report for Oracle Solaris Studio Fortran; he had hoped to fix it for
> 12.3 but ran out of time.
>
> Lacking a convincing argument that column 1 is the correct one, I follow
> the crowd by believing that column 25 is correct. For GCC/gfortran, that's
> tracked as problem report (PR) 52251.
>
> The interpretation request is:
> 000027 "Sequential formatted I/O: position of the left tab"
> at http://j3-fortran.org/doc/year/02/02-006c2.txt
>
> The crucial sentence (according to DISCUSSION) is:
> "Immediately prior to data transfer, the left tab limit becomes defined as
> the character position of the current record."

I don't see the left tab limit as the central point in this matter.

The way I understand it, the t edit descriptor in the first write
statement in the example doesn't _change_ the positioning of the file.
It only _specifies_ the position at which the next character will be
transferred. Since this is non-advancing output, the file positioning at
the start of the second write statement will be exactly the same as at
the start of the first write statement (i.e. at position 1 of the first
record), so the left tab limit will also be the same.
Now, when the next data transfer takes place, it will do so starting at
the position previously specified by the t edit descriptor.

So in my view the crucial matter is whether the specification made by
the t edit descriptor is persistent from one write statement to the
next. I don't see anything in the standard denying this. It simply states:

"The Tn edit descriptor indicates that the transmission of the next
character to or from a record is to occur at the nth character position
of the record, relative to the left tab limit."

Nothing about whether this transmission of the next character has to
actually take place during the same output statement.

Now that I'm thinking about it, I'm starting to wonder if this behaviour
should also hold for advancing output. Leaving out the advance specifier
from the first write statement would then lead to an empty record,
followed by a record containing 24 blanks and the string "Hello".

In this context I'm also wondering if there is any significance in the
difference in wording between the text for the Tn descriptor and that
for the TLn and TRn descriptors.
The first one speaks about "transmission of the next character to or
from A record" (emphasis mine), while the other two speak about
"transmission of the next character to or from THE record". This seems
to imply that, while TLn and TRn specifications are only valid within
the current record, the Tn specification remains valid even if the next
data transfer takes place in a subsequent record.
(I fear this interpretation is stretching it a bit, and that I'm reading
to much into this minute difference, but I can't get the idea out of my
head that there is significance to every word in the standard.)

All I know for sure right now, is that this is a tricky subject.

Erik.

Dick Hendrickson

unread,
Feb 16, 2012, 2:36:43 PM2/16/12
to
On 2/15/12 8:04 PM, Erik Toussaint wrote:
> I hesitate to argue with the professionals and experts on such a
> technical matter, but I've been reading through the standard and I can't
> really find an airtight explanation of the process; it seems to me to
> allow some room for interpretation, so regard this as nothing more than
> my attempt at making sense of things.
>
Don't worry, the professionals have at least 3 different
answers/reasons. ;)

>
> On 15-2-2012 8:42, Tobias Burnus wrote:
>> Dick Hendrickson<dick.hen...@att.net> wrote:
>>>> Different compilers are giving me different output for the following
>>>>
>>>> Write( *, '( t25 )', Advance = 'No' )
>>>> Write( *, '( "Hello" )' )
>>>
>>> I think that only the version with 25 leading blanks is correct.
>
> 25 blanks or 24 blanks and "Hello" starting at position 25?
Yes, pure carelessness on my part. Off by 1.

>
>
>> [...]
>>> There was an interpretation about Tabbing and next-records many years
>>> ago; but I think it was related to the wording for what the new left-tab
>>> position was.
>>
>> I have asked at the J3 mailing list and got a reply by Bob Corbett of Sun
>> (now Oracle). He believes that the interpretation request (which he
>> filled)
>> is about this issue and that having 25 blanks is correct. There is a
>> pending
>> bug report for Oracle Solaris Studio Fortran; he had hoped to fix it for
>> 12.3 but ran out of time.
>>
>> Lacking a convincing argument that column 1 is the correct one, I follow
>> the crowd by believing that column 25 is correct. For GCC/gfortran,
>> that's
>> tracked as problem report (PR) 52251.
>>
>> The interpretation request is:
>> 000027 "Sequential formatted I/O: position of the left tab"
>> at http://j3-fortran.org/doc/year/02/02-006c2.txt
>>
>> The crucial sentence (according to DISCUSSION) is:
>> "Immediately prior to data transfer, the left tab limit becomes
>> defined as
>> the character position of the current record."
>
> I don't see the left tab limit as the central point in this matter.

It is, but the reason isn't obvious. I'm sure it says elsewhere that
nothing can go before the left-tab limit. Thus, if the LTL is at column
25 for the second write statement, then "Hello" can't be to the left of 25.

As Richard said, "character position of the current record" doesn't
appear to be (well?) defined. But (clearly?) it must be where the next
character would be read or written. At the end of the first write
statement, it has to be column 25. Anything else wouldn't make sense,
IMO. And, the quoted line above makes the new LTL be column 25 for the
second write.

I think putting the LTL at the current position for subsequent
non-advancing I/O was a judgment call. It seems logical to me, but I
can't remember any "good reason."

It could have been clearer in the standard.

I just checked a F2003 book and it says
"...the left tabbing limit. This position is normally the first position
of the current record or the current position in a stream file, but, if
the previous operation on the file was a nonadvancing
formatted data transfer, the left tabbing limit is the current position
within the record before the current data transfer begins." That book
doesn't define "current position" very well either.

Dick Hendrickson

glen herrmannsfeldt

unread,
Feb 16, 2012, 2:51:06 PM2/16/12
to
Dick Hendrickson <dick.hen...@att.net> wrote:

(snip)

>>>>> Write( *, '( t25 )', Advance = 'No' )
>>>>> Write( *, '( "Hello" )' )

(snip)
> It is, but the reason isn't obvious. I'm sure it says elsewhere that
> nothing can go before the left-tab limit. Thus, if the LTL is at
> column 25 for the second write statement, then "Hello" can't be
> to the left of 25.

> As Richard said, "character position of the current record" doesn't
> appear to be (well?) defined. But (clearly?) it must be where the next
> character would be read or written. At the end of the first write
> statement, it has to be column 25. Anything else wouldn't make sense,
> IMO. And, the quoted line above makes the new LTL be column 25 for the
> second write.

> I think putting the LTL at the current position for subsequent
> non-advancing I/O was a judgment call. It seems logical to me,
> but I can't remember any "good reason."

With stream I/O and non-record oriented file systems, there is
really no limit to the position.

I remember the first time I learned this, not so long after I
started working with unix, I had a postscript file with many
megabytes of data and 0 lines. (Lines were terminated with CR,
and unix wc counts LF.) (That was long enough ago that a few
megabytes was a large file.)

> It could have been clearer in the standard.

> I just checked a F2003 book and it says
> "...the left tabbing limit. This position is normally the first
> position of the current record or the current position in a stream
> file, but, if the previous operation on the file was a nonadvancing
> formatted data transfer, the left tabbing limit is the current
> position within the record before the current data transfer begins."
> That book doesn't define "current position" very well either.

Note that a program could write essentially an infinite stream
of non-advancing I/O. (Writing to a pipe, so as not to fill up
any physical disk.) If it has to keep track of it, then you
have to ask what happens when the position counter overflows.

T was added to Fortran when records had fixed length, and
a buffer was allocated. Moving around within a buffer is
easy. Repositioning within a stream, isn't.

DO I=1,1000000000
Write( *, '( x25 )', Advance = 'No' )
ENDDO
Write( *, '( t1, "Hello" )' )

-- glen
0 new messages