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

Is this a bug?

5 views
Skip to first unread message

David Sagan

unread,
Aug 31, 2010, 8:24:01 AM8/31/10
to
Hello:

Consider the following code:

program test
implicit none
character(40) line
line = 'Hello World!'
write (line, '(i3, 2x, a)') 7, trim(line)
print *, line
end program

When compiled with lahey or intel compilers the output when the
program is run is:
7 Hello World!
As I would expect. With the gfortran compiler (v4.5.1) the output is:
7 7lo World!

Now my question is is this a bug or does the fortran standard allow
such behavior?

Thanks, David

Arjen Markus

unread,
Aug 31, 2010, 8:30:06 AM8/31/10
to

This is definitely a bug - the output makes no sense. I suggest you
report it to the gfortran people.

Regards,

Arjen

mecej4

unread,
Aug 31, 2010, 8:47:17 AM8/31/10
to
David Sagan wrote:

> Hello:
>
> Consider the following code:
>
> program test
> implicit none
> character(40) line
> line = 'Hello World!'
> write (line, '(i3, 2x, a)') 7, trim(line)

The program is not as innocent as it may appear.

The internal unit ('line') to which a formatted write is being done is also
a member of the I/O list.

Section 9.5.3.4 of the Fortran 2003 Standard says "If an internal ?le has
been speci?ed, an input/output list item shall not be in the ?le or
associated with the ?le."

> print *, line
> end program
>
> When compiled with lahey or intel compilers the output when the
> program is run is:
> 7 Hello World!
> As I would expect. With the gfortran compiler (v4.5.1) the output is:
> 7 7lo World!
>
> Now my question is is this a bug or does the fortran standard allow
> such behavior?
>
> Thanks, David

-- mecej4

mecej4

unread,
Aug 31, 2010, 8:50:30 AM8/31/10
to
mecej4 wrote:

> David Sagan wrote:
>
>> Hello:
>>
>> Consider the following code:
>>
>> program test
>> implicit none
>> character(40) line
>> line = 'Hello World!'
>> write (line, '(i3, 2x, a)') 7, trim(line)
>
> The program is not as innocent as it may appear.
>
> The internal unit ('line') to which a formatted write is being done is
> also a member of the I/O list.
>
> Section 9.5.3.4 of the Fortran 2003 Standard says "If an internal ?le has
> been speci?ed, an input/output list item shall not be in the ?le or
> associated with the ?le."
>

Sorry, cut-and-paste from the PDF document replaced the ligature 'fi' by
'?', and I did not notice it before posting.

-- mecej4

Arjen Markus

unread,
Aug 31, 2010, 9:00:10 AM8/31/10
to
> > -- mecej4- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -

Oops, missed that bit - you are right: the program is not conforming.
(I figured it was a strange bug in the formatting)

Regards,

Arjen

robin

unread,
Aug 31, 2010, 9:56:49 AM8/31/10
to
"mecej4" <mec...@nyetspam.operamail.com> wrote in message news:i5itki$nlv$1...@news.eternal-september.org...

| David Sagan wrote:
|
| > Hello:
| >
| > Consider the following code:
| >
| > program test
| > implicit none
| > character(40) line
| > line = 'Hello World!'
| > write (line, '(i3, 2x, a)') 7, trim(line)
|
| The program is not as innocent as it may appear.
|
| The internal unit ('line') to which a formatted write is being done is also
| a member of the I/O list.

Well, yes and no.
To my mind, if LINE were in the list, then what you say [below] would apply.
However, TRIM(LINE) is a function reference that returns a value.
If TRIM(LINE) returns an address and length, then there would be trouble.
If TRIM(LINE) returns a temporary, there should be no trouble at all.

FX

unread,
Aug 31, 2010, 10:13:58 AM8/31/10
to
> Well, yes and no.

Oh, we got a new shiny quantum Standard? You only get to know if the code
is standard conformant when you observe it?

> To my mind, if LINE were in the list, then what you say [below] would
> apply. However, TRIM(LINE) is a function reference that returns a
> value. If TRIM(LINE) returns an address and length, then there would be
> trouble. If TRIM(LINE) returns a temporary, there should be no trouble
> at all.

I searched very hard the normative text of the standard for the word
temporary, but I cannot find it there.

--
FX

mecej4

unread,
Aug 31, 2010, 10:22:18 AM8/31/10
to
robin wrote:

> "mecej4" <mec...@nyetspam.operamail.com> wrote in message
> news:i5itki$nlv$1...@news.eternal-september.org...
> | David Sagan wrote:
> |
> | > Hello:
> | >
> | > Consider the following code:
> | >
> | > program test
> | > implicit none
> | > character(40) line
> | > line = 'Hello World!'
> | > write (line, '(i3, 2x, a)') 7, trim(line)
> |
> | The program is not as innocent as it may appear.
> |
> | The internal unit ('line') to which a formatted write is being done is
> | also a member of the I/O list.
>
> Well, yes and no.
> To my mind, if LINE were in the list, then what you say [below] would
> apply. However, TRIM(LINE) is a function reference that returns a value.
> If TRIM(LINE) returns an address and length, then there would be trouble.
> If TRIM(LINE) returns a temporary, there should be no trouble at all.

I see your point. If implementation is through a temporary, a compiler has
to be careful not to bypass the formation of the temporary in the special
case of TRIM(LINE) being a perfect match to LINE, i.e., when no trailing
blanks are present in LINE.

It is not clear to me what "associated with the file" means, and whether
TRIM(LINE) is "associated" with LINE (see quote from standard, below).

-- mecej4

mecej4

unread,
Aug 31, 2010, 11:15:10 AM8/31/10
to
FX wrote:

>> Well, yes and no.
>
> Oh, we got a new shiny quantum Standard? You only get to know if the code
> is standard conformant when you observe it?

Heisenbugs, Bohrbugs and Mandelbugs have been recognized for many years!

-- mecej4

steve

unread,
Aug 31, 2010, 12:50:58 PM8/31/10
to

See Section 16.5.7 in Fortran 2003. IMHO, the code is nonconforming.

--
steve

mecej4

unread,
Aug 31, 2010, 1:52:53 PM8/31/10
to
steve wrote:

Steve:

I have only the draft standard, J3/04-007. In that, Section 16.5.7, titled
"Variable definition context", lists item 7: "An internal-file-variable in
a write-stmt" as one of the contexts in which the appearance of a variable
implies definition/undefinition of the variable. The preamble of the section
states that "..variables are prohibited from appearing in a syntactic
context that would imply definition or undefinition...".

Is that wording the one that you used to conclude that the Sagan's code is
nonconforming?

-- mecej4

Richard Maine

unread,
Aug 31, 2010, 2:19:04 PM8/31/10
to
steve <kar...@comcast.net> wrote:

I agree that the code is nonconforming, but I don't see what 16.5.7 has
to do with the question at all. That seems such a distant relation that
I wondered whether it was a typo for some other section, but I couldn't
come up with a likely one. The closest thing I can see 16.5.7 saying is
that appearance as an internal file counts as a variable definition
context; but I don't see how one would go anywhere from that towards
answering either the original question or the above association
question.

TRIM(LINE) is not associated with LINE. (I don't see anything in 16.5.7
or anywhere else that implies that it is). I think that's the wrong
direction here.

I wish the standard had been worded more "robustly" on this. I'm not
quite sure whether the writers of the restriction in question forgot
about possibilities like this or whether they took the parsimonious
approach of writing a restriction that hit only the cases that weren't
already covered elsewhere. I don't tend to like that parsimonious
approach, though I have seen it (and heard people argue for it) in other
places in the standard. I'd a lot rather just give the restrictions in a
broad form. That can result in there being redundant restrictions
against some things, but I don't see the harm in that. In exchange, you
get something that is easier to read and more robust. I've seen people
argue that we should write things like "if X then Y" even though Y is
true independent of X. The argument is that the cases without X are
already covered. That kind of writing drives me batty (yes, now you know
why). Anyway, back to specifics....

I would say that 12.4.1.7(1) is the prohibition that hits this case.
LINE is associated with a dummy argument of TRIM. Action that affects
the value of LINE is being taken other than through the dummy argument.

The word I would say is most subject to question here is the "while"
that is the first word of 12.4.1.7. Is the action of writing to the
internal file happening while the argument association exists? I would
say "yes" because the standard does not establish a particular time
during the WRITE statement when the action of defining the internal file
happens. One might imagine an implementation that evaluated all the I/O
list items before doing any of the writing, but the standard doesn't
specify that. Indeed, the previously cited restriction against I/O list
items being associated with the file would not make much sense if that
kind of ordering were implied. So I think that one has to interpret the
action of "affecting the value" as happening during the whole WRITE
statement.

Note that the "while" question has a different answer in the case of
assignment statements. It is explicit in the standard (as of f90) that
the evaluation of the right-hand-side of an assignment statement happens
prior to assigning the resulting value to the variable. Thus the action
affecting the variable does not happen "while" any argument associations
in the expression exist.

If one were looking for loopholes (as a good editor is supposed to do),
I might wonder about the internal write case where the I/O list had a
concatenation instead of a function reference. My argument above applies
only to function arguments. I bet it is also intended to be invalid to
do concatenation of the internal file in the I/O list, but darned if I
see the prohibition of that case. Wanna bet somebody overlooked that
one? I sure wish the prohibition had just been written more broadly,
insomuch as I think it was intended to be broad. It probably belongs in
9.11, which has a bunch of simillar restrictions on things in an I/O
statement affecting other things in the same I/O statement. There are
restrictions there that are close, but not quite hitting it. An internal
file does appear in a specifier in the I/O statement, but the I/O list
items aren't in specifiers.

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

steve

unread,
Aug 31, 2010, 2:31:10 PM8/31/10
to

16.5.7 Variable definition context

Some variables are prohibited from appearing in a syntactic
context that would imply definition or undefinition of the
variable (5.1.2.7, 5.1.2.12, 12.6). The following are the
contexts in which the appearance of a variable implies such
definition or undefinition of the variable:

...

(6) An internal-file-variable in a write-stmt,

...

The offending line

write (line, '(i3, 2x, a)') 7, trim(line)

could be implemented as

1) 'line' appears in write() as internal file, fill it with blanks,
and position
it at location 1. Causes an undefinition of line in trim()?
2) transfer ' 7' to line (i.e., the I3 format), set current location
to 4
3) transfer ' ' to line, set current location to 7
4) transfer trim(line) to line. Whoops.

It could also be implemented as

1) position line at 1
2 transfer ' 7' to line (i.e., the I3 format), set current location
to 4.
Causes an undefinition of line in trim()?
3) transfer ' ' to line, set current location to 7
4) transfer trim(line) to line. Whoops.
5) pad with blanks

AFAIK, a write statement is not like an assignment where one has a
RHS, which is evaluated first and then assigned to the LHS (possibly
with a type conversion). I could be mistaken, but I believe a Fortran
processor can transfer the list of entities in a sequential order.
Thus,
writing the '7' occurs before a processor has the opportunity to 'see'
the trim(line).


9.5.3.4 Data transfer

page 196, lines 18-19

All values are transmitted to or from the entities specified by a list
item
prior to the processing of any succeeding list item for all data
transfer
input/output statements.

PS: I'm sure Richard will correct me if I've misinterpreted the
standard.

--
steve


Richard Maine

unread,
Aug 31, 2010, 2:59:45 PM8/31/10
to
steve <kar...@comcast.net> wrote:

> 16.5.7 Variable definition context
>
> Some variables are prohibited from appearing in a syntactic
> context that would imply definition or undefinition of the
> variable (5.1.2.7, 5.1.2.12, 12.6). The following are the
> contexts in which the appearance of a variable implies such
> definition or undefinition of the variable:
>
> ...
>
> (6) An internal-file-variable in a write-stmt,

Yes. So LINE appears in a variable definition context. Right. But you
haven't quoted anything that says it is prohibited from appearing in a
variable definition context. The above just says that there exist some
such prohibitions, but you haven't cited one.
...
> could be implemented as

"could be implemented as" doesn't count as a specification of the
standard. That's more of an illustration of why the standard might
specify something. One still actually has to find the specification. See
my other post (probably written at the same time as you were writing the
above one).

Although it is vaguely related, the line of argument I advanced has
nothing to do with 16.5.7. The stuff relating to 16.5.7 tends to be
syntactic and usually has the words "variable definition context." For
example, see C545, which says ... "shall not appear in a variable
definition context".

The hard part is not figuring out that the internal write causes the
internal file to becoime defined; that part counts as pretty obvious.
What takes more searching is to find why that prohibits the code in
question. Giving an example of an implementation strategy that might get
it wrong doesn't cut it. That could just imply that it was a disallowed
implementation strategy.

> AFAIK, a write statement is not like an assignment where one has a
> RHS, which is evaluated first and then assigned to the LHS (possibly
> with a type conversion).

...


> I believe a Fortran
> processor can transfer the list of entities in a sequential order.

I agree except that I think you are arguing backwards from the
conclusion. Admitedly, one sometimes has to do that in order to guess
the committee's intention, but that's not the way the logic is supposed
to work.

It is the restrictions on the code that allow such implementation, so
one needs to look for those restrictions. One doesn't say that an
implementation like that is supposed to work and therefore some
restrictions must exist. Yes, that's exactly the kind of thing the
committee often does in comming up with the restrictions, but if you
have to argue in that direction, then the committee didn't do their job
right and an erratum is probably in order. The usual deduction is more
the other way - that the standard specifies these restrictions, which
means that an implementation like that would work.

In this case, I think I found the restriction (see my other post). I
don't see one for the concatenation case, though, as my argument applied
only to function arguments.

glen herrmannsfeldt

unread,
Aug 31, 2010, 3:44:44 PM8/31/10
to
robin <rob...@dodo.com.au> wrote:

(snip)

> | > write (line, '(i3, 2x, a)') 7, trim(line)

> | The program is not as innocent as it may appear.

> | The internal unit ('line') to which a formatted write is being
> | done is also a member of the I/O list.

> Well, yes and no.
> To my mind, if LINE were in the list, then what you say [below] would apply.
> However, TRIM(LINE) is a function reference that returns a value.
> If TRIM(LINE) returns an address and length, then there would be trouble.
> If TRIM(LINE) returns a temporary, there should be no trouble at all.

No. That might be true for a subroutine call, but this is I/O.
There is no requirement that trim(line) be evaluated before the I/O
operation of 7 is done.

I have seen C code the equivalent of:

write (line, '(a, 2x, i3)') line, 7

That is, it depends on the previous contents of line being written
to line before later list items. It tends to work but is, I believe,
not standard for C. It may also work in Fortran, but again I
believe not standard.

In C, with I/O done by function calls, it is usual that all
arguments are evaluated before the function call is made.

That is not true for Fortran I/O lists, which is the underlying
cause for the recursive I/O effect.



> | Section 9.5.3.4 of the Fortran 2003 Standard says "If an internal ?le has
> | been speci?ed, an input/output list item shall not be in the ?le or
> | associated with the ?le."

Put fi in place of the ? and it makes more sense.

-- glen

mecej4

unread,
Aug 31, 2010, 3:49:25 PM8/31/10
to
Richard Maine wrote:

> steve <kar...@comcast.net> wrote:
>
>> On Aug 31, 7:22 am, mecej4 <mec...@nyetspam.operamail.com> wrote:
>
>> See Section 16.5.7 in Fortran 2003. IMHO, the code is nonconforming.
>
> I agree that the code is nonconforming, but I don't see what 16.5.7 has
> to do with the question at all.

<--CUT-->.



> I would say that 12.4.1.7(1) is the prohibition that hits this case.
> LINE is associated with a dummy argument of TRIM. Action that affects
> the value of LINE is being taken other than through the dummy argument.
>

Richard, thanks for your helpful discussion.

However, I have a remaining doubt. TRIM being an intrinsic function, is
pure. Therefore, its arguments (only 1 in this case) have INTENT(IN) and,
presumably, the user wants the function to be evaluated with argument values
equal to those that existed prior to the execution of this internal WRITE
statement.

This viewpoint may be illustrated more strongly by considering a slightly
different WRITE statement:

INTEGER :: ll
...
ll = len(trim(line))

write (line, '(A, 2x, I2)') line(1:ll-4),ll

instead of that given by the OP:

write (line, '(i3, 2x, a)') 7, trim(line)

According to your reading of the standard, even the revised WRITE is
forbidden, is it not?

(I have assumed that 'line' has enough trailing blanks that appending the
encoded length does not cause the string to become longer than its allocated
length)

-- mecej4

glen herrmannsfeldt

unread,
Aug 31, 2010, 3:55:42 PM8/31/10
to
steve <kar...@comcast.net> wrote:
(snip)


> 1) 'line' appears in write() as internal file, fill it with blanks,
> and position it at location 1.

Reminds me of a question related to WATFIV many years ago. I believe
it is not usual to fill the buffer with blanks at I/O initialization,
and then not copy excess blanks in with format descriptors,
but it seems that is what WATFIV does. That is, it copies only
non-blanks to the buffer for I/O list items. The interesting cases
come with the T format descriptor. I am not sure the exact case,
but consider:

write(*,1) 3,7
1 format(i3,t2,i4)

WATFIV would write ' 3 7' where others would write ' 7',
putting three blanks and a 7 into the buffer.

-- glen

Richard Maine

unread,
Aug 31, 2010, 4:14:59 PM8/31/10
to
mecej4 <mec...@nyetspam.operamail.com> wrote:

> Richard Maine wrote:

> > I would say that 12.4.1.7(1) is the prohibition that hits this case.
> > LINE is associated with a dummy argument of TRIM. Action that affects
> > the value of LINE is being taken other than through the dummy argument.

...

> However, I have a remaining doubt. TRIM being an intrinsic function, is
> pure. Therefore, its arguments (only 1 in this case) have INTENT(IN)

Ok so far.

> presumably, the user wants the function to be evaluated with argument values
> equal to those that existed prior to the execution of this internal WRITE
> statement.

That, however, seems like a non-sequitur that has nothing to do with
what the standard says. The restriction I cite says nothing about being
pure or not. Users "presumably wanting" something is not a specification
in the standard. Users want many things that aren't so. Some of the
wants are quire reasonable things to want; that still doesn't make them
part of the standard.

I can find nothing anywhere - not in the discussion of I/O, of purity,
of intent, or anywhere else - that says anything even vaguely like that.
I can't even find anything that hints at it. It just seems like a
complete non-sequitur. Why would purity make users want that particular
characteristic anyway. Wouldn't they want it just as much for non-pure
functions?

For example, I'm quite confident that users wanted

line = 'prefix' // line

to work in f77. Certainly enough of them asked here about exactly that
kind of thing. I wanted it to work to. But it didn't; not until f90.



> This viewpoint may be illustrated more strongly by considering a slightly
> different WRITE statement:
>
> INTEGER :: ll
> ...
> ll = len(trim(line))
>
> write (line, '(A, 2x, I2)') line(1:ll-4),ll
>
> instead of that given by the OP:
>
> write (line, '(i3, 2x, a)') 7, trim(line)
>
> According to your reading of the standard, even the revised WRITE is
> forbidden, is it not?

No, that has nothing to do with what I cited. Note that the central part
of my discussion was about the word "while" and the justification that
line was being modified "while" it was also associated with a dummy
argument of trim. In your new example, that is certainly not the case;
the invocation of trim is unambiguously done prior to the write
statement.

Your new example is forbidden, but not because of the argument I
mentioned. Instead, in your new example an I/O list item is associated
with the internal file. trim(line) is not associated with line, but
line(1:ii-4) (or any other sibstring of line) is associated with line.

Richard Maine

unread,
Aug 31, 2010, 4:14:59 PM8/31/10
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> No. That might be true for a subroutine call, but this is I/O.
> There is no requirement that trim(line) be evaluated before the I/O
> operation of 7 is done.

Well, for that matter, there is no such requirement for subroutines
either. Although subroutine calls are described as first evaluating the
arguments, there are restrictions on subroutines that effectively allow
for "lazy evaluation" because you can't tell the difference in legal
code.

Richard Maine

unread,
Aug 31, 2010, 4:22:37 PM8/31/10
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> Reminds me of a question related to WATFIV many years ago. I believe
> it is not usual to fill the buffer with blanks at I/O initialization,
> and then not copy excess blanks in with format descriptors,
> but it seems that is what WATFIV does. That is, it copies only
> non-blanks to the buffer for I/O list items. The interesting cases
> come with the T format descriptor. I am not sure the exact case,
> but consider:
>
> write(*,1) 3,7
> 1 format(i3,t2,i4)
>
> WATFIV would write ' 3 7' where others would write ' 7',
> putting three blanks and a 7 into the buffer.

The standard makes that one pretty explicit. The ' 3 7' result would
violate the standard. At least it would violate any recent ones. I
wouldn't guarantee f66 (and I don't feel like checking). Heck, I don't
even recall for sure whether T format was in f66.

Now X format has some related quirks. I forget whether or not it blank
fills when used like that in conjunction with T, but it never extends
the lenggth of a record. This a format of (5x,i3) writes a record of
length 8, but (i3,5x) writes a record of length 3. If you add an i1 as
in (i3,5x,i1), then suddenly the 5x does blank fill and the the i1
effectively added 6 characters to the record.

glen herrmannsfeldt

unread,
Aug 31, 2010, 4:39:29 PM8/31/10
to
Richard Maine <nos...@see.signature> wrote:
> glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

>> Reminds me of a question related to WATFIV many years ago. I believe
>> it is not usual to fill the buffer with blanks at I/O initialization,
>> and then not copy excess blanks in with format descriptors,
>> but it seems that is what WATFIV does. That is, it copies only
>> non-blanks to the buffer for I/O list items. The interesting cases
>> come with the T format descriptor. I am not sure the exact case,
>> but consider:

>> write(*,1) 3,7
>> 1 format(i3,t2,i4)

>> WATFIV would write ' 3 7' where others would write ' 7',
>> putting three blanks and a 7 into the buffer.

> The standard makes that one pretty explicit. The ' 3 7' result would
> violate the standard. At least it would violate any recent ones. I
> wouldn't guarantee f66 (and I don't feel like checking). Heck, I don't
> even recall for sure whether T format was in f66.

It seems not to be in Fortran 66, but it is in OS/360 Fortran IV,
which WATFIV is supposed to be based on. It seems that this
distinction was not documented, though.



> Now X format has some related quirks. I forget whether or not it blank
> fills when used like that in conjunction with T, but it never extends
> the lenggth of a record. This a format of (5x,i3) writes a record of
> length 8, but (i3,5x) writes a record of length 3. If you add an i1 as
> in (i3,5x,i1), then suddenly the 5x does blank fill and the the i1
> effectively added 6 characters to the record.

So:

1 format(i3,t1,3x,i1)

-- glen

steve

unread,
Aug 31, 2010, 5:38:10 PM8/31/10
to
On Aug 31, 11:59 am, nos...@see.signature (Richard Maine) wrote:
> steve <kar...@comcast.net> wrote:
> > 16.5.7  Variable definition context
>
> > Some variables are prohibited from appearing in a syntactic
> > context that would imply definition or undefinition of the
> > variable (5.1.2.7, 5.1.2.12, 12.6).  The following are the
> > contexts in which the appearance of a variable implies such
> > definition or undefinition of the variable:
>
> >    ...
>
> >    (6) An internal-file-variable in a write-stmt,
>
> Yes. So LINE appears in a variable definition context. Right. But you
> haven't quoted anything that says it is prohibited from appearing in a
> variable definition context. The above just says that there exist some
> such prohibitions, but you haven't cited one.

(snip)

> I agree except that I think you are arguing backwards from the

> conclusion. Admittedly, one sometimes has to do that in order to guess


> the committee's intention, but that's not the way the logic is supposed
> to work.

Thanks for filling in the blanks. Your statement about arguing
backwards reminded me of my grad school days where I was
working on some quantum mechanics or EM homework. I
sometimes knew the answer, but had no idea how to get from
point A to B. Starting from answer, I could often derive the
question.

:)

--
steve

Richard Maine

unread,
Aug 31, 2010, 5:58:49 PM8/31/10
to
steve <kar...@comcast.net> wrote:

> Your statement about arguing
> backwards reminded me of my grad school days where I was
> working on some quantum mechanics or EM homework. I
> sometimes knew the answer, but had no idea how to get from
> point A to B. Starting from answer, I could often derive the
> question.

Obligatory xkcd link <http://xkcd.com/759/>.

And don't forget to read the mouseover text or you won't understand the
connection. :-)

Paul van Delst

unread,
Aug 31, 2010, 6:02:32 PM8/31/10
to
Richard Maine wrote:
> Users "presumably wanting" something is not a specification
> in the standard. Users want many things that aren't so. Some of the
> wants are quire reasonable things to want;

For some reason the above words make me think of a scene in an old star trek movie (the one where they go back in time
to the 80's).

Scottie is sitting in front of an old macintosh (high end back then) and starts talking to it. The present day engineer
type in the room tells him to use the mouse. So Scottie picks up the mouse and talks to *that*. (hee hee) Eventually he
groks how to use keyboard+mouse (shaking his head at the antediluvian interface).

It would be neat to have a language+compiler+hardware that did exactly what I wanted just by talking to it. Scary, but
neat. :o)

Anyway....

cheers,

paulv

nm...@cam.ac.uk

unread,
Aug 31, 2010, 6:12:23 PM8/31/10
to
In article <1jo3af8.153z3dye23q20N%nos...@see.signature>,

Richard Maine <nos...@see.signature> wrote:
>
>For example, I'm quite confident that users wanted
>
> line = 'prefix' // line
>
>to work in f77. Certainly enough of them asked here about exactly that
>kind of thing. I wanted it to work to. But it didn't; not until f90.

And quite a lot didn't, for very good reasons - many of us didn't
like the approach taken precisely because it led to that sort of
thing. The point was that, in the late 1970s, non-transparent
memory management of the sort that Fortran 90 introduces was a
real pain, not least for portability.

However, things have changed, and memory limits aren't the issue
they were :-)


Regards,
Nick Maclaren.

jfh

unread,
Aug 31, 2010, 8:21:47 PM8/31/10
to

To test Richard's point about concatenation I wrote the following two
programs,one of which uses the // operator and one concatenates only
by having a list of two output items. My own advice the other day
would suggest that the programs may not be standard-conforming,
because different compilers gave different run-time output. If Richard
says a program is standard-conforming he's almost always right, and if
there's a bug in the standard one can hardly blame compiler-writers
for interpreting it in different ways. But was anyone unsurprised to
see what three compilers did with the second program?

Program using //

! F2003 12.4.1.7(1) seems not to disallow this program. It prints:
! foobar 666does this work? barfoo if compiled with ifort, but
! foobar 666foobar 666work? barfoo with gfortran, g95, Sun f95.
implicit no
character:: line*40 = 'does this work?'
write(line,"(A,I0,A)") 'foobar ',666, line(1:15)//' barfoo '
print *,line
end

Program not using //

! F2003 12.4.1.7(1) seems not to disallow this program. It prints:
! ' 666 Was that OK? ' if compiled with ifort, but
! ' 666 666 666 666 666 666' with gfortran, g95, or Sun f95.
implicit none
character:: line*24 = ' Was that OK?'
write(line,"(I4,A)") 666, line(1:20)
print *,"'",line,"'"
end

-- John Harper

Richard Maine

unread,
Aug 31, 2010, 8:53:38 PM8/31/10
to
jfh <john....@vuw.ac.nz> wrote:

> Program not using //
>
> ! F2003 12.4.1.7(1) seems not to disallow this program. It prints:
> ! ' 666 Was that OK? ' if compiled with ifort, but
> ! ' 666 666 666 666 666 666' with gfortran, g95, or Sun f95.
> implicit none
> character:: line*24 = ' Was that OK?'
> write(line,"(I4,A)") 666, line(1:20)
> print *,"'",line,"'"
> end

Note that, although I agree that 12.4.1.7(1) says nothing about this
one, I think that mecej4's quote from 9.5.3.4 makes it nonconforming
because line(1:20) is associated with line (or at least partially
associated... I didn't check into that particular gritty distinction to
see whether I think it matters).

Your example using // is the one I can't find a prohibition against (but
that I think probably should have been prohibitted).

robin

unread,
Sep 3, 2010, 9:28:50 AM9/3/10
to
"glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message news:i5jpa1$nmu$1...@speranza.aioe.org...

| It seems not to be in Fortran 66, but it is in OS/360 Fortran IV,
| which WATFIV is supposed to be based on.

WATFIV was based on WATFOR.

WATFOR was an implementation of FORTRAN IV,
with additions and exceptions.

The only thing that WATFOR had in common with OS/360 FORTRAN IV
was that it ran on an IBM/360.


robin

unread,
Sep 3, 2010, 9:29:56 AM9/3/10
to
"glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message news:i5jmnu$jih$1...@speranza.aioe.org...

| Reminds me of a question related to WATFIV many years ago. I believe
| it is not usual to fill the buffer with blanks at I/O initialization,
| and then not copy excess blanks in with format descriptors,
| but it seems that is what WATFIV does. That is, it copies only
| non-blanks to the buffer for I/O list items.

For that to work, the buffer must be initialized at the beginning to all blanks.
If only non-blanks are copied to the output, every line would
print rubbish in the ninitialized positions.

| The interesting cases
| come with the T format descriptor. I am not sure the exact case,
| but consider:
|
| write(*,1) 3,7
| 1 format(i3,t2,i4)
|
| WATFIV would write ' 3 7' where others would write ' 7',
| putting three blanks and a 7 into the buffer.

and rubbish in positions 1and 2, which are never initialized --
according to your hypothesis.


0 new messages