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

continuation line with only comments

3 views
Skip to first unread message

anal...@hotmail.com

unread,
Apr 16, 2009, 4:51:28 PM4/16/09
to
is it legal to write

a = 0 &
& ! comments

kar...@comcast.net

unread,
Apr 16, 2009, 6:07:12 PM4/16/09
to

no.

--
steve

anal...@hotmail.com

unread,
Apr 16, 2009, 7:36:08 PM4/16/09
to

I thought so - my compiler just cribbed about it and I fail to
understand why this feature cannot be provided (imagine that you are
trying out differnt ways to calculate a parameter and it would be
useful to record the result next to each version and if the formula
plus result is too long you might want to put the results as comments
in the continuation line).

Sjouke Burry

unread,
Apr 16, 2009, 8:20:35 PM4/16/09
to

Besides, whats wrong with:

a = 0
! line above:blablablablabla............

?????
Also called the KISS principle.

mecej4

unread,
Apr 16, 2009, 8:24:25 PM4/16/09
to

What happens if you remove the '&' from the comment line?

-- mecej4

dpb

unread,
Apr 16, 2009, 8:26:47 PM4/16/09
to
mecej4 wrote:
...

> What happens if you remove the '&' from the comment line?

Syntax error on the preceding line unless remove the '&' from it as
well. (Making it two separate lines as opposed to a continuation, of
course.)

--

mecej4

unread,
Apr 16, 2009, 8:51:14 PM4/16/09
to
What I had in mind was something like this, which g95 accepts:

program tst90cont
integer :: i,j
do i=1,5
j=2*i- &
! The r.h.s. is continued to the next non-comment line
! enter notes here to explain the formula
3
end do
print *,j
end program tst90cont

-- mecej4

kar...@comcast.net

unread,
Apr 16, 2009, 11:57:26 PM4/16/09
to

Assuming free-form (because I don't care about fixed-form), the
standard says

3.3.1.3 Free form statement continuation
The character "&" is used to indicate that the current statement is
continued on the next line that is not a comment line. Comment lines
shall not be continued; an "&" in a comment has no effect. Comments
may occur within a continued statement. When used for continuation,
the "&" is not part of the statement. No line shall contain
a single "&" as the only nonblank character or as the only nonblank
character before an "!" that initiates a comment.

Notice the last sentence.

Richard Maine

unread,
Apr 17, 2009, 12:04:27 AM4/17/09
to
<kar...@comcast.net> wrote:

> Assuming free-form (because I don't care about fixed-form), the
> standard says
>
> 3.3.1.3 Free form statement continuation
> The character "&" is used to indicate that the current statement is
> continued on the next line that is not a comment line. Comment lines
> shall not be continued; an "&" in a comment has no effect. Comments
> may occur within a continued statement. When used for continuation,
> the "&" is not part of the statement. No line shall contain
> a single "&" as the only nonblank character or as the only nonblank
> character before an "!" that initiates a comment.
>
> Notice the last sentence.

And yes, there is a reason for that. Such a line would be ambiguous. The
& could either be the optional & at the beginning of a continued line,
or it could be an indication of a further continuation, with the
optional beginning & omitted.

Note that a line such as

&& !-- Some comment here

is fine because

1. Well, because the standard says it is :-)

and

2. It is unambiguous.

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

nm...@cam.ac.uk

unread,
Apr 17, 2009, 4:44:44 AM4/17/09
to
In article <1iyaaab.jiz3gd1lhu8uqN%nos...@see.signature>,

Richard Maine <nos...@see.signature> wrote:
><kar...@comcast.net> wrote:
>
>> Assuming free-form (because I don't care about fixed-form), the
>> standard says
>>
>> 3.3.1.3 Free form statement continuation
>> The character "&" is used to indicate that the current statement is
>> continued on the next line that is not a comment line. Comment lines
>> shall not be continued; an "&" in a comment has no effect. Comments
>> may occur within a continued statement. When used for continuation,
>> the "&" is not part of the statement. No line shall contain
>> a single "&" as the only nonblank character or as the only nonblank
>> character before an "!" that initiates a comment.
>>
>> Notice the last sentence.
>
>And yes, there is a reason for that. Such a line would be ambiguous. The
>& could either be the optional & at the beginning of a continued line,
>or it could be an indication of a further continuation, with the
>optional beginning & omitted.
>
>Note that a line such as
>
> && !-- Some comment here
>
>is fine because
>
>1. Well, because the standard says it is :-)
>
>and
>
>2. It is unambiguous.

And

3. It is needed.

PRINT *, 'Print rather a lot of ampersands &&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'


Regards,
Nick Maclaren.

none

unread,
Apr 17, 2009, 5:56:58 AM4/17/09
to

The quote you were given from the standard explained that this is legal -
comments can be within a continuation sequence. However, the comment
itself is not part of the continuation sequence. This, to my mind, makes
the restrictions imposed by the standard easier to understand - you can
have an emdebbed comment, but in a manner that makes it easy for the
parser to recognise that the whole line can be discarded from analysis.

anal...@hotmail.com

unread,
Apr 17, 2009, 8:15:40 AM4/17/09
to
> Notice the last sentence.- Hide quoted text -
>
> - Show quoted text -


I have also given up on fixed form and since printing source code has
become a rarity for me, I like to use a typical full screen of about
110 characters.

At any rate I found a cute workaround

a= 0 &
& ; continue ! comments

the "continue" is vacuous from a fortran standpoint but preserves the
unity of the statement and comments.

actually

a = 0 &
& ; ! comments also works - but I wounder if thats a vendor extension.

dpb

unread,
Apr 17, 2009, 9:31:56 AM4/17/09
to
mecej4 wrote:
...

> What I had in mind was something like this, which g95 accepts:
>
...

> j=2*i- &
> ! The r.h.s. is continued to the next non-comment line
> ! enter notes here to explain the formula
> 3
...

Yeah, I had a lapse in forgetting the ampersand beginning the line is
optional rather than required except when a token is broken (a sorry
thing to do, but...)

--

Dick Hendrickson

unread,
Apr 17, 2009, 11:55:58 AM4/17/09
to

It's been a long time since we've had a challenge in this group
(Where's Dave Franck when we need him?). So, WITHOUT running
the following abridged version of Nick's program, how many will
"rather a lot" be? (I abridged it only to make the counting
less tedious)

PRINT *, 'Print rather a lot of ampersands &&&&&
&&&&&

&&&&&'
end

Dick Hendrickson

robin

unread,
Apr 17, 2009, 8:27:41 PM4/17/09
to
<anal...@hotmail.com> wrote in message
news:214d5347-1529-416d...@z5g2000yqn.googlegroups.com...

>At any rate I found a cute workaround

>a= 0 &
>& ; continue ! comments

>the "continue" is vacuous from a fortran standpoint but preserves the
unity of the statement and comments.

"Continue" is redundant. The semicolon is sufficient.
Also the "&" on the continued line is redundant.

>actually

>a = 0 &
>& ; ! comments also works - but I wounder if thats a vendor extension.

No.


Ron Shepard

unread,
Apr 18, 2009, 1:30:54 AM4/18/09
to
In article <189Gl.4304$y61....@news-server.bigpond.net.au>,
"robin" <rob...@bigpond.com> wrote:

> >a= 0 &
> >& ; continue ! comments
>
> >the "continue" is vacuous from a fortran standpoint but preserves the
> unity of the statement and comments.
>
> "Continue" is redundant. The semicolon is sufficient.
> Also the "&" on the continued line is redundant.

Instead of "redundant", I would say rather that it is "optional".

I find that I usually include the optional & in continuation lines
because it makes it easier to control the indentation. And it does
remove all doubt that the line is indeed a continuation.

BTW, I remember reading about this restriction before and wondered why
it existed. Now I understand why.

$.02 -Ron Shepard

Dan Nagle

unread,
Apr 18, 2009, 8:55:39 AM4/18/09
to
Hello,

On 2009-04-17 20:27:41 -0400, "robin" <rob...@bigpond.com> said:

> "Continue" is redundant. The semicolon is sufficient.

continue is an executable statement, the ; is not.
Therefore, a continue can be used to signal the end
of the declaratives, and cause any error messages
from the declaratives to be printed. (With f77-style
declarations, the compiler might not know it's
got inconsistent declarations until it knows it's
seen them all.)

With proper indenting, a continue and return pair
may be used to delimit visually the executable code
of a subprogram.

Also, a continue may be used to evaluate a function
without storing the result anywhere, as in

if( f( x) == 0.0 ) continue

Note that a print statement containing the reference
stores the result in the i/o buffers.

> Also the "&" on the continued line is redundant.

Redundancy may be useful to the eye to emphasize
the programmer's intentions.

Null executable statements are useful at times
in the same way zero may be a useful number.

--
Cheers!

Dan Nagle

nm...@cam.ac.uk

unread,
Apr 18, 2009, 9:04:38 AM4/18/09
to
In article <2009041808554116807-dannagle@verizonnet>,

Dan Nagle <dann...@verizon.net> wrote:
>
>> Also the "&" on the continued line is redundant.
>
>Redundancy may be useful to the eye to emphasize
>the programmer's intentions.

Indeed. I have occasionally seen and written code like the following:

w = fred ( x + ((( y + z ))) )

It's a lot safer to use the following code, but there are occasionally
circumstances where it causes other problems:

w = y + z
w = fred (x + w)

The redundant parentheses make it very clear what the code assumes.


Regards,
Nick Maclaren.

Ron Shepard

unread,
Apr 18, 2009, 5:03:56 PM4/18/09
to
In article <2009041808554116807-dannagle@verizonnet>,
Dan Nagle <dann...@verizon.net> wrote:

> Also, a continue may be used to evaluate a function
> without storing the result anywhere, as in
>
> if( f( x) == 0.0 ) continue

I wonder about this. Could a compiler optimize away the function
reference in this case?

$.02 -Ron Shepard

Ron Shepard

unread,
Apr 18, 2009, 5:18:17 PM4/18/09
to
In article
<iE1Gl.129175$4m1.1...@bgtnsc05-news.ops.worldnet.att.net>,
Dick Hendrickson <dick.hen...@att.net> wrote:

> PRINT *, 'Print rather a lot of ampersands &&&&&
> &&&&&
> &&&&&'
> end

How many? Good question. Also, would the string have embedded
spaces?

$ gfortran test_continue.f90
Warning: '&' not allowed by itself in line 2

But no answer.

$.02 -Ron Shepard

Dan Nagle

unread,
Apr 18, 2009, 5:48:50 PM4/18/09
to
Hello,

On 2009-04-18 17:03:56 -0400, Ron Shepard
<ron-s...@NOSPAM.comcast.net> said:

Oh, I suppose it's possible.
But robin's point is completely wrong.


--
Cheers!

Dan Nagle

Tobias Burnus

unread,
Apr 18, 2009, 6:38:26 PM4/18/09
to
Hi,

Note that is only a warning and not an error thus running ./a.out gives
the correct result. This bogus error is only printed for an odd number
of &, which makes it a really special case.


Tobias

PS: I filled a bugreport.

robin

unread,
Apr 18, 2009, 7:31:32 PM4/18/09
to
"Ron Shepard" <ron-s...@NOSPAM.comcast.net> wrote in message
news:ron-shepard-7DC3...@news60.forteinc.com...

> In article <189Gl.4304$y61....@news-server.bigpond.net.au>,
> "robin" <rob...@bigpond.com> wrote:
>
> > >a= 0 &
> > >& ; continue ! comments
> >
> > >the "continue" is vacuous from a fortran standpoint but preserves the
> > unity of the statement and comments.
> >
> > "Continue" is redundant. The semicolon is sufficient.
> > Also the "&" on the continued line is redundant.
>
> Instead of "redundant", I would say rather that it is "optional".

It is redundant because it is unneeded clutter,
and doesn't change the execution of the program.

> I find that I usually include the optional & in continuation lines
> because it makes it easier to control the indentation. And it does
> remove all doubt that the line is indeed a continuation.

There's never any doubt because the statement body on the
previous line finishes with an &.


robin

unread,
Apr 18, 2009, 7:31:33 PM4/18/09
to
"Dan Nagle" <dann...@verizon.net> wrote in message news:2009041808554116807-dannagle@verizonnet...

> Hello,
>
> On 2009-04-17 20:27:41 -0400, "robin" <rob...@bigpond.com> said:
>
> > "Continue" is redundant. The semicolon is sufficient.
>
> continue is an executable statement, the ; is not.

The semicolon is a statement separator/terminator.

> Therefore, a continue can be used to signal the end
> of the declaratives,

It could be, but is innecessary.
The next executable statement will do that.
I cannot recall ever seeing a CONTINUE statement
at the head of the executable instructions.

> and cause any error messages
> from the declaratives to be printed.

Syntax error messages in declarations can be issued as soon as
an error is encounterred in the particular statement --
and normally are.

> (With f77-style
> declarations, the compiler might not know it's
> got inconsistent declarations until it knows it's
> seen them all.)

> With proper indenting, a continue and return pair
> may be used to delimit visually the executable code
> of a subprogram.

They could be, but again what's the point.
After the declarations, the executable code
is patently obvious.

> Also, a continue may be used to evaluate a function
> without storing the result anywhere, as in
>
> if( f( x) == 0.0 ) continue

Fine, if you don't mind getting a warning message for that.
Most people would be satisfied with
waste = f(x),
which requires fewer keystrokes and doesn't leave
the reader wondering why on earth someone wrote
the silly statement
if (f(x) == 0.0) continue.

> Note that a print statement containing the reference
> stores the result in the i/o buffers.

That's totally irrelevant to the use of CONTINUE statement.

> > Also the "&" on the continued line is redundant.
>
> Redundancy may be useful to the eye to emphasize
> the programmer's intentions.

Perhaps, but it's un-needed clutter.

> Null executable statements are useful at times
> in the same way zero may be a useful number.

Since the advent of END DO and Block IF, the need for a
CONTINUE statement has diminished considerably.


Ron Shepard

unread,
Apr 18, 2009, 7:40:37 PM4/18/09
to
In article <74v332F...@mid.uni-berlin.de>,
Tobias Burnus <bur...@net-b.de> wrote:

> >> PRINT *, 'Print rather a lot of ampersands &&&&&
> >> &&&&&
> >> &&&&&'
> >> end
> >
> > How many? Good question. Also, would the string have embedded
> > spaces?
> >
> > $ gfortran test_continue.f90
> > Warning: '&' not allowed by itself in line 2
> >
> > But no answer.
>
> Note that is only a warning and not an error thus running ./a.out gives
> the correct result. This bogus error is only printed for an odd number
> of &, which makes it a really special case.

You are right, I jumped to conclusions. From gfortran I get:

Print rather a lot of ampersands &&&&&&&&&&&

And from the ABSOFT compiler I get the same thing.

Print rather a lot of ampersands &&&&&&&&&&&

So it looks like the first line contributes 4, the second line
contributes 3, and the last line contributes 4, for a total of 11.
And neither compiler put embedded spaces, which would happen if the
first & of the continuation had been taken as a string character
rather than an optional continuation character.

$.02 -Ron Shepard

Ron Shepard

unread,
Apr 18, 2009, 7:44:51 PM4/18/09
to
In article <2009041817485316807-dannagle@verizonnet>,
Dan Nagle <dann...@verizon.net> wrote:

> Hello,
>
> On 2009-04-18 17:03:56 -0400, Ron Shepard
> <ron-s...@NOSPAM.comcast.net> said:
>
> > In article <2009041808554116807-dannagle@verizonnet>,
> > Dan Nagle <dann...@verizon.net> wrote:
>
> >> if( f( x) == 0.0 ) continue
> >
> > I wonder about this. Could a compiler optimize away the function
> > reference in this case?
>
> Oh, I suppose it's possible.

I really meant to ask if a standard-conforming compiler could
optimize away the function reference.

> But robin's point is completely wrong.

I was not referring to the original question, I got distracted by
this tangential issue.

$.02 -Ron Shepard

Dick Hendrickson

unread,
Apr 18, 2009, 9:14:15 PM4/18/09
to
Ron Shepard wrote:
> In article <2009041817485316807-dannagle@verizonnet>,
> Dan Nagle <dann...@verizon.net> wrote:
>
>> Hello,
>>
>> On 2009-04-18 17:03:56 -0400, Ron Shepard
>> <ron-s...@NOSPAM.comcast.net> said:
>>
>>> In article <2009041808554116807-dannagle@verizonnet>,
>>> Dan Nagle <dann...@verizon.net> wrote:
>>>> if( f( x) == 0.0 ) continue
>>> I wonder about this. Could a compiler optimize away the function
>>> reference in this case?
>> Oh, I suppose it's possible.
>
> I really meant to ask if a standard-conforming compiler could
> optimize away the function reference.
>

The simple answer is "it's a matter of opinion".

There have been many threads on c.l.f about functions with
side effects and whether or not the compiler must evaluate
the function. There are at least two points of view and
no sign of the people on either side changing their
minds.

The standard says "clearly" that a processor need not
evaluate an expression completely is the result can
be determined some other way. Everybody
believes this means that compilers can freely
do what is commonly called short-circuiting, especially
in logical expressions. In
if ( x > 0.0 .or. f(x)) ...
the compiler need not evaluate f(x) if x > 0.0. But, it
is allowed to evaluate f(x). So, the side-effects of
f(x) are undefined because you can't portably rely on
f(x) [not] being evaluated. Similar things apply to
expressions like x*f(x) if the compiler can do
enough analysis to prove that x is zero; there is
no need to evaluate f(x) (unless, maybe, the compiler
can't prove that f(x) isn't a NaN or Inf).

The problem is (in my opinion) deciding which expressions
can be evaluated by other means. The other side
believes the standard is quite general and allows the
compiler to evaluate all expressions "some other way" and
NEVER invoke any functions. (They don't specify how
the expression "f(x) == 0" can be evaluated without
evaluating f(x); but they don't have to.)

Carried to this extreme, you can never count on any function
every being evaluated and you can, obviously, never count
on side effects in a function. Personally, I don't think
this is the intent of the standard. I think portable
computing is enhanced by encouraging user written
functions to take a peek at their arguments and
abort (the ultimate side-effect) if the arguments are out
of range and therefore processors should evaluate functions
when they aren't "obviously" optimized away.

People who I have tremendous respect for think I'm batty :( .

So, if you want to play it safe, never write functions which
have side effects since a good enough optimizer can remove
them.

Dick Hendrickson

glen herrmannsfeldt

unread,
Apr 19, 2009, 1:25:17 AM4/19/09
to

glen herrmannsfeldt

unread,
Apr 19, 2009, 1:30:46 AM4/19/09
to
Ron Shepard <ron-s...@nospam.comcast.net> wrote:
> <iE1Gl.129175$4m1.1...@bgtnsc05-news.ops.worldnet.att.net>,
> Dick Hendrickson <dick.hen...@att.net> wrote:

>> PRINT *, 'Print rather a lot of ampersands &&&&&
>> &&&&&
>> &&&&&'
>> end

> How many? Good question.

> $ gfortran test_continue.f90
> Warning: '&' not allowed by itself in line 2

That sounds wrong to me. g95 seems to do it.

> Also, would the string have embedded spaces?

I believe that is the main reason for starting the continuation
line with &. That is, so leading blanks aren't part of the string.

For continuations not in the middle of a string, and not in
the middle of a keyword, operator, or identifier, blanks
don't matter. Inside a string constant, they do.

So, the last & of the first two lines, and the first of the
last two lines should not be part of the string.
That seems to agree with g95. It looks like a gfortran bug.

-- glen

glen herrmannsfeldt

unread,
Apr 19, 2009, 1:44:24 AM4/19/09
to
Dick Hendrickson <dick.hen...@att.net> wrote:
> Ron Shepard wrote:
>> In article <2009041817485316807-dannagle@verizonnet>,
>> Dan Nagle <dann...@verizon.net> wrote:

>>> On 2009-04-18 17:03:56 -0400, Ron Shepard
>>> <ron-s...@NOSPAM.comcast.net> said:

>>>> In article <2009041808554116807-dannagle@verizonnet>,
>>>> Dan Nagle <dann...@verizon.net> wrote:
>>>>> if( f( x) == 0.0 ) continue

>>>> I wonder about this. Could a compiler optimize
>>>> away the function reference in this case?

>>> Oh, I suppose it's possible.

>> I really meant to ask if a standard-conforming compiler could
>> optimize away the function reference.

> The simple answer is "it's a matter of opinion".

I believe that at the highest optimization levels one
should expect some things to not follow the strictest
interpretation of the standard. That is the tradeoff
for the speed of optimized code.

(snip)



> The standard says "clearly" that a processor need not
> evaluate an expression completely is the result can
> be determined some other way. Everybody
> believes this means that compilers can freely
> do what is commonly called short-circuiting, especially
> in logical expressions. In
> if ( x > 0.0 .or. f(x)) ...


C requires short circuiting. I remember a story from
some years ago, some would instead of

if(x>0.) f(x)

write:

x>0. && f(x);

(In C, an expression doesn't have to be assigned to a variable.)

The interesting part is that they found that the compiler
generated better code for:

x>0. && f(x) && 1;

> the compiler need not evaluate f(x) if x > 0.0. But, it
> is allowed to evaluate f(x). So, the side-effects of
> f(x) are undefined because you can't portably rely on
> f(x) [not] being evaluated.

(snip)



> Carried to this extreme, you can never count on any function
> every being evaluated and you can, obviously, never count
> on side effects in a function. Personally, I don't think
> this is the intent of the standard. I think portable
> computing is enhanced by encouraging user written
> functions to take a peek at their arguments and
> abort (the ultimate side-effect) if the arguments are out
> of range and therefore processors should evaluate functions
> when they aren't "obviously" optimized away.

For certain definitions of "obviously."



> People who I have tremendous respect for think I'm batty :( .

> So, if you want to play it safe, never write functions which
> have side effects since a good enough optimizer can remove
> them.

-- glen

Richard Maine

unread,
Apr 19, 2009, 2:41:07 AM4/19/09
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> >> PRINT *, 'Print rather a lot of ampersands &&&&&
> >> &&&&&
> >> &&&&&'
> >> end

...


> > $ gfortran test_continue.f90
> > Warning: '&' not allowed by itself in line 2

...


> It looks like a gfortran bug.

Note that Tobias apparently agrees as he already said he filed a bug
report. For what it is worth, I agree also. In fact, I'd say the message
was self-evidently a bug, even if the code weren't valid, insomuch as
the message refers to an & on a line by itself and there is no such
thing in the code.

Dan Nagle

unread,
Apr 19, 2009, 7:08:55 AM4/19/09
to
Hello,

On 2009-04-18 19:31:33 -0400, "robin" <rob...@bigpond.com> said:

>> Therefore, a continue can be used to signal the end
>> of the declaratives,
>
> It could be, but is innecessary.
> The next executable statement will do that.

And it might lead to a confusing message if the first statement
has the name whose declaration is inconsistent.

> I cannot recall ever seeing a CONTINUE statement
> at the head of the executable instructions.

You've never read my code.

>
>> and cause any error messages
>> from the declaratives to be printed.
>
> Syntax error messages in declarations can be issued as soon as
> an error is encounterred in the particular statement --
> and normally are.

The point is about _inconsistent_ declarations,
not mere syntax errors.

<snip>

>> if( f( x) == 0.0 ) continue
>
> Fine, if you don't mind getting a warning message for that.
> Most people would be satisfied with
> waste = f(x),
> which requires fewer keystrokes and doesn't leave
> the reader wondering why on earth someone wrote
> the silly statement
> if (f(x) == 0.0) continue.

But it does change the memory of the program,
which is the point I'm making.

>> Note that a print statement containing the reference
>> stores the result in the i/o buffers.
>
> That's totally irrelevant to the use of CONTINUE statement.

No, it's the point I'm making here, that a function
can be evaluated without storing the result _anywhere_.

--
Cheers!

Dan Nagle

nm...@cam.ac.uk

unread,
Apr 19, 2009, 7:20:01 AM4/19/09
to
In article <2009041907085416807-dannagle@verizonnet>,

Dan Nagle <dann...@verizon.net> wrote:
>On 2009-04-18 19:31:33 -0400, "robin" <rob...@bigpond.com> said:
>
>>> Therefore, a continue can be used to signal the end
>>> of the declaratives,
>>
>> It could be, but is innecessary.
>> The next executable statement will do that.
>
>And it might lead to a confusing message if the first statement
>has the name whose declaration is inconsistent.

Or even a valid program in older Fortrans! An undeclared array
with the first statement an assigment as the first executable
statement is usually a valid statement function.

>>> if( f( x) == 0.0 ) continue
>>
>> Fine, if you don't mind getting a warning message for that.
>> Most people would be satisfied with
>> waste = f(x),
>> which requires fewer keystrokes and doesn't leave
>> the reader wondering why on earth someone wrote
>> the silly statement
>> if (f(x) == 0.0) continue.
>
>But it does change the memory of the program,
>which is the point I'm making.

It MAY do so, but highly optimising compilers will eliminate it
entirely.

>>> Note that a print statement containing the reference
>>> stores the result in the i/o buffers.
>>
>> That's totally irrelevant to the use of CONTINUE statement.
>
>No, it's the point I'm making here, that a function
>can be evaluated without storing the result _anywhere_.

STOP fred()


Regards,
Nick Maclaren.

robin

unread,
Apr 19, 2009, 10:36:03 AM4/19/09
to
"Ron Shepard" <ron-s...@NOSPAM.comcast.net> wrote in message
news:ron-shepard-F43F...@forte.easynews.com...

No.


robin

unread,
Apr 19, 2009, 10:36:03 AM4/19/09
to
"Dan Nagle" <dann...@verizon.net> wrote in message news:2009041817485316807-dannagle@verizonnet...

> Hello,
>
> On 2009-04-18 17:03:56 -0400, Ron Shepard
> <ron-s...@NOSPAM.comcast.net> said:
>
> > In article <2009041808554116807-dannagle@verizonnet>,
> > Dan Nagle <dann...@verizon.net> wrote:
>
> >> if( f( x) == 0.0 ) continue
> >
> > I wonder about this. Could a compiler optimize away the function
> > reference in this case?
>
> Oh, I suppose it's possible.

Under what circumstances?

> But robin's point is completely wrong.

And what point was that?


robin

unread,
Apr 19, 2009, 10:36:04 AM4/19/09
to
"Dan Nagle" <dann...@verizon.net> wrote in message news:2009041808554116807-dannagle@verizonnet...

> Also, a continue may be used to evaluate a function
> without storing the result anywhere, as in
>
> if( f( x) == 0.0 ) continue

CONTINUE doesn't evaluate anything.
It's a "do nothing" statement.
The result of the function is stored somewhere, for
comparison with the value 0.0

At the very least, the value of the function is
stored in the variable nominated by the function.

After that, the value may be returned on a stack
or in a register, depending on the compiler and hardware
available.
After that, the value is compared with zero, or tested
for zero (again, depending on the hardware or compiler).


Gary Scott

unread,
Apr 19, 2009, 10:38:25 AM4/19/09
to
glen herrmannsfeldt wrote:
> Dick Hendrickson <dick.hen...@att.net> wrote:
>
>>Ron Shepard wrote:
>>
>>>In article <2009041817485316807-dannagle@verizonnet>,
>>> Dan Nagle <dann...@verizon.net> wrote:
>
>
>
>>>>On 2009-04-18 17:03:56 -0400, Ron Shepard
>>>><ron-s...@NOSPAM.comcast.net> said:
>
>
>>>>>In article <2009041808554116807-dannagle@verizonnet>,
>>>>> Dan Nagle <dann...@verizon.net> wrote:
>>>>>
>>>>>>if( f( x) == 0.0 ) continue
>
>
>>>>>I wonder about this. Could a compiler optimize
>>>>>away the function reference in this case?
>
>
>>>>Oh, I suppose it's possible.
>
>
>
>>>I really meant to ask if a standard-conforming compiler could
>>>optimize away the function reference.
>
>
>
>>The simple answer is "it's a matter of opinion".
>
>
> I believe that at the highest optimization levels one
> should expect some things to not follow the strictest
> interpretation of the standard. That is the tradeoff
> for the speed of optimized code.
>

Nooooooo! No matter how optimized, it is absolutely never acceptable to
not achieve the global results that would be achieved if a function were
completely executed. That includes side effects. The only exception to
this rule should be if the programmer explicitly defined a function to
be pure/without side effects. If there is any ambiguity whatsoever in
the standard, then it needs to be fixed. If any compiler does not
achieve side effects for any reason, including high levels of
optimization, it needs to be fixed.


snip

>
>
> -- glen


--

Gary Scott
mailto:garylscott@sbcglobal dot net

Fortran Library: http://www.fortranlib.com

Support the Original G95 Project: http://www.g95.org
-OR-
Support the GNU GFortran Project: http://gcc.gnu.org/fortran/index.html

If you want to do the impossible, don't hire an expert because he knows
it can't be done.

-- Henry Ford

Dan Nagle

unread,
Apr 19, 2009, 11:16:55 AM4/19/09
to
Hello,

On 2009-04-19 10:36:03 -0400, "robin" <rob...@bigpond.com> said:

> "Ron Shepard" <ron-s...@NOSPAM.comcast.net> wrote in message
> news:ron-shepard-F43F...@forte.easynews.com...

>> I wonder about this. Could a compiler optimize away the function


>> reference in this case?
>
> No.

As Dick rather patiently explained, there are differing views
on this point. In fact, different statements in the standard
may be taken as leading to contradictory conclusions.

Also, the case of a pure function is clearly different
from that of a non-pure function.

--
Cheers!

Dan Nagle

Dan Nagle

unread,
Apr 19, 2009, 11:22:25 AM4/19/09
to
Hello,

On 2009-04-19 10:36:04 -0400, "robin" <rob...@bigpond.com> said:

> At the very least, the value of the function is
> stored in the variable nominated by the function.

Most likely, in a register on most modern hardware.

> After that, the value may be returned on a stack
> or in a register, depending on the compiler and hardware
> available.

Most likely, in a register on most modern hardware.
The return value will certainly *not* be on the stack
when the function has been in-lined.

> After that, the value is compared with zero, or tested
> for zero (again, depending on the hardware or compiler).

Most likely, an instruction to compare a register
with zero is emitted, with no data memory traffic.

oo

--
Cheers!

Dan Nagle

nm...@cam.ac.uk

unread,
Apr 19, 2009, 12:08:13 PM4/19/09
to
In article <2009041911165516807-dannagle@verizonnet>,

Dan Nagle <dann...@verizon.net> wrote:
>On 2009-04-19 10:36:03 -0400, "robin" <rob...@bigpond.com> said:
>> "Ron Shepard" <ron-s...@NOSPAM.comcast.net> wrote in message
>> news:ron-shepard-F43F...@forte.easynews.com...
>
>>> I wonder about this. Could a compiler optimize away the function
>>> reference in this case?
>>
>> No.
>
>As Dick rather patiently explained, there are differing views
>on this point. In fact, different statements in the standard
>may be taken as leading to contradictory conclusions.

However, standard practice since Fortran 66 is that a compiler MAY
optimise it away, but will do so only if the user requests aggressive
optimisation. And cautious programmers don't write such code, for
that reason.

In my view, this is the worst ambiguity in the Fortran standard; I am
one of many people who has tried to clean the area up, and retired
hurt. It probably wasn't resolvable even by Fortran 66.


Regards,
Nick Maclaren.

Dan Nagle

unread,
Apr 19, 2009, 12:25:08 PM4/19/09
to
Hello,

On 2009-04-19 12:08:13 -0400, nm...@cam.ac.uk said:

> However, standard practice since Fortran 66 is that a compiler MAY
> optimise it away, but will do so only if the user requests aggressive
> optimisation. And cautious programmers don't write such code, for
> that reason.

There was a proposal for a volatile attribute for functions,
which would have been an anti-pure attribute. But it was
a rather complicated proposal, and was made during the closing
meetings of f03. It was later adjudged to be too big too late
and it was dropped. A processor would have been obliged
to call the function once for each textual appearance, IIRC.

Since then, the person who made the proposal has quit J3,
a victim of lack of academic support for standards. :-(
The papers are still in the archive if you would like
to read them.

--
Cheers!

Dan Nagle

Dan Nagle

unread,
Apr 19, 2009, 12:32:41 PM4/19/09
to
Hello,

I don't mean to follow up my own post,
but a quick check shows that Nick's comments
are in paper 03-151, and a possible solution
is in paper 03-163.

Richard Maine

unread,
Apr 19, 2009, 1:03:32 PM4/19/09
to
<nm...@cam.ac.uk> wrote:

> In article <2009041907085416807-dannagle@verizonnet>,
> Dan Nagle <dann...@verizon.net> wrote:
> >On 2009-04-18 19:31:33 -0400, "robin" <rob...@bigpond.com> said:
> >
> >>> Therefore, a continue can be used to signal the end
> >>> of the declaratives,
> >>
> >> It could be, but is innecessary.
> >> The next executable statement will do that.
> >
> >And it might lead to a confusing message if the first statement
> >has the name whose declaration is inconsistent.
>
> Or even a valid program in older Fortrans! An undeclared array
> with the first statement an assigment as the first executable
> statement is usually a valid statement function.

Yes. Confusions beteen statement functions and assignments are rampant,
both in humans and compiles. There is also the old VAX form of a
parameter statement. (I suppose I shouldn't call it the VAX form because
DEC allegedly took it from a preiminary draft of f77 and later regretted
having done so). It is also ambiguous with an assignment statement in
fixed source form.

I don't happen to use a CONTINUE statement to signal the end of the
declarations myself, but I can see the sense of it. My style does have a
comment separating declarations from executable code, but that helps
only the human reader - not the compiler.

Gary Scott

unread,
Apr 19, 2009, 1:07:26 PM4/19/09
to
Richard Maine wrote:

> <nm...@cam.ac.uk> wrote:
>
>
>>In article <2009041907085416807-dannagle@verizonnet>,
>>Dan Nagle <dann...@verizon.net> wrote:
>>
>>>On 2009-04-18 19:31:33 -0400, "robin" <rob...@bigpond.com> said:
>>>
>>>
>>>>>Therefore, a continue can be used to signal the end
>>>>>of the declaratives,
>>>>
>>>>It could be, but is innecessary.
>>>>The next executable statement will do that.
>>>
>>>And it might lead to a confusing message if the first statement
>>>has the name whose declaration is inconsistent.
>>
>>Or even a valid program in older Fortrans! An undeclared array
>>with the first statement an assigment as the first executable
>>statement is usually a valid statement function.
>
>
> Yes. Confusions beteen statement functions and assignments are rampant,
> both in humans and compiles. There is also the old VAX form of a
> parameter statement. (I suppose I shouldn't call it the VAX form because
> DEC allegedly took it from a preiminary draft of f77 and later regretted
> having done so). It is also ambiguous with an assignment statement in
> fixed source form.
>
> I don't happen to use a CONTINUE statement to signal the end of the
> declarations myself, but I can see the sense of it. My style does have a
> comment separating declarations from executable code, but that helps
> only the human reader - not the compiler.
>

My first statement is typically the setting of a return code to a
specific value (usually zero). Nearly all of my procedures provide a
return code.

James Van Buskirk

unread,
Apr 19, 2009, 1:32:18 PM4/19/09
to
"Dan Nagle" <dann...@verizon.net> wrote in message
news:2009041911165516807-dannagle@verizonnet...

> Also, the case of a pure function is clearly different
> from that of a non-pure function.

How so?

C:\gfortran\clf\count_equal>type count_equal.f90
module ops
implicit none
interface operator(==)
module procedure equals
end interface operator(==)
integer :: mycount = 0
contains
function equals(x,y)
character(*), intent(in) :: x
real, intent(in) :: y
logical equals
real data

mycount = mycount+1
read(x,*) data
equals = data == y
end function equals

pure function f(x)
real, intent(in) :: x
character(f_len(x)) f
character(100) temp

write(temp,*) x
f = adjustl(temp)
end function f

pure function f_len(x)
real, intent(in) :: x
integer f_len
character(100) temp

write(temp,*) x
f_len = len_trim(adjustl(temp))
end function f_len
end module ops

program count_equals
use ops
implicit none
integer i
real x
character(20) stuff

do i = 1, 20
x = i-10
write(stuff,*) x
write(*,*) f(x) == 0.0
end do

write(*,*) 'mycount = ', mycount

do i = 1, 20
x = i-10
write(stuff,*) x
if(f(x) == 0.0) continue
end do

write(*,*) 'mycount = ', mycount
end program count_equals

C:\gfortran\clf\count_equal>gfortran count_equal.f90 -ocount_equal

C:\gfortran\clf\count_equal>count_equal
F
F
F
F
F
F
F
F
F
T
F
F
F
F
F
F
F
F
F
F
mycount = 20
mycount = 40

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


Dan Nagle

unread,
Apr 19, 2009, 2:03:34 PM4/19/09
to
Hello,

On 2009-04-19 13:32:18 -0400, "James Van Buskirk" <not_...@comcast.net> said:

> "Dan Nagle" <dann...@verizon.net> wrote in message
> news:2009041911165516807-dannagle@verizonnet...
>
>> Also, the case of a pure function is clearly different
>> from that of a non-pure function.
>
> How so?

Since a pure function has no side-effects, it may be elided.
Not that any compiler actually does, but one could.

So given, a = b + 0.0 * f( x)
the f( x) might disappear, if f is pure.

--
Cheers!

Dan Nagle

Richard Maine

unread,
Apr 19, 2009, 2:14:33 PM4/19/09
to
Dan Nagle <dann...@verizon.net> wrote:

> Hello,
>
> On 2009-04-19 13:32:18 -0400, "James Van Buskirk" <not_...@comcast.net>
said:
>
> > "Dan Nagle" <dann...@verizon.net> wrote in message
> > news:2009041911165516807-dannagle@verizonnet...
> >
> >> Also, the case of a pure function is clearly different
> >> from that of a non-pure function.
> >
> > How so?
>
> Since a pure function has no side-effects, it may be elided.

Well, since some people think a non-pure one may also be elided, and
that is exactly the area of the disagreement mentioned by Dick, I'd
argue that it isn't so "clearly" different. I assume that you aren't
saying that one side is "clearly" right.

Perhaps though, what you mean is that it is clearly different in that
there is no substantiative debate. That is a difference I do see. - a
difference in the level of debatability rather than necessarily a
difference in the answer.

Dan Nagle

unread,
Apr 19, 2009, 2:28:30 PM4/19/09
to
Hello,

On 2009-04-19 14:14:33 -0400, nos...@see.signature (Richard Maine) said:

> Perhaps though, what you mean is that it is clearly different in that
> there is no substantiative debate. That is a difference I do see. - a
> difference in the level of debatability rather than necessarily a
> difference in the answer.

Point taken.

--
Cheers!

Dan Nagle

nm...@cam.ac.uk

unread,
Apr 19, 2009, 3:08:16 PM4/19/09
to
In article <1iyf30s.951dxy103zyh4N%nos...@see.signature>,

Richard Maine <nos...@see.signature> wrote:
>
>Perhaps though, what you mean is that it is clearly different in that
>there is no substantiative debate. That is a difference I do see. - a
>difference in the level of debatability rather than necessarily a
>difference in the answer.

There are only two things that seem to be clear:

PURE functions can be eliminated whenever the compiler chooses.

Impure functions are a historical wormcan of major proportions.


Regards,
Nick Maclaren.

James Van Buskirk

unread,
Apr 19, 2009, 3:43:52 PM4/19/09
to
"Dan Nagle" <dann...@verizon.net> wrote in message
news:2009041914033516807-dannagle@verizonnet...

>> How so?

Nope. You snipped my demonstration of the fallacy in your argument.
Go back and look at the code and output I posted in:

http://groups.google.com/group/comp.lang.fortran/msg/bc2a2d84710ac3cd?hl=en

where I showed that it's not only function f that must be pure in
your example. It could trivially be extended to show that f(x)
must be evaluated in some potential contexts of your above line
of code, even if function f is pure.

Dan Nagle

unread,
Apr 19, 2009, 4:36:44 PM4/19/09
to
Hello,

On 2009-04-19 15:43:52 -0400, "James Van Buskirk" <not_...@comcast.net> said:
>
> Nope. You snipped my demonstration of the fallacy in your argument.
> Go back and look at the code and output I posted in:
>
> http://groups.google.com/group/comp.lang.fortran/msg/bc2a2d84710ac3cd?hl=en
>
> where I showed that it's not only function f that must be pure in
> your example. It could trivially be extended to show that f(x)
> must be evaluated in some potential contexts of your above line
> of code, even if function f is pure.

I read your example. Your == is not pure. What are you demonstrating?

--
Cheers!

Dan Nagle

James Van Buskirk

unread,
Apr 19, 2009, 5:04:53 PM4/19/09
to
"Dan Nagle" <dann...@verizon.net> wrote in message
news:2009041916364616807-dannagle@verizonnet...

> I read your example. Your == is not pure. What are you demonstrating?

That everything involved in executing the statement must be pure, not
just one little part of it. You could have composed a statement such
as:

if(f(x)) continue

if you wanted to restrict attention to pure function f, but in your
case you unnecessarily inserted operator(==) and made no mention of
it. In your subsequent snippet, you have exposure to operator(*),
operator(+), and assignment(=). OK, so I guess I need to post
another example, here everything is pure:

C:\gfortran\clf\count_equal>type ex2.f90
module ops
implicit none
interface operator(*)
module procedure times
end interface operator(*)
contains
pure function times(x,y)
character(*), intent(in) :: y
real, intent(in) :: x
real times
real data

read(y,*) data
times = (x+epsilon(x))*data
end function times

pure function f(x)
real, intent(in) :: x
character(f_len(x)) f
character(100) temp

write(temp,*) x
f = adjustl(temp)
end function f

pure function f_len(x)
real, intent(in) :: x
integer f_len
character(100) temp

write(temp,*) x
f_len = len_trim(adjustl(temp))
end function f_len
end module ops

program count_equals
use ops
implicit none
integer i
real x

real a
real b
real total

total = 0
b = epsilon(a)


do i = 1, 20
x = i-10

a = b + 0.0 * f( x)

total = total+a
end do

write(*,*) 'total = ', total
write(*,*) '20*b = ', 20*b
end program count_equals

C:\gfortran\clf\count_equal>gfortran ex2.f90 -oex2

C:\gfortran\clf\count_equal>ex2
total = 3.57627869E-06
20*b = 2.38418579E-06

Dan Nagle

unread,
Apr 19, 2009, 6:10:16 PM4/19/09
to
Hello,

On 2009-04-19 17:04:53 -0400, "James Van Buskirk" <not_...@comcast.net> said:

> "Dan Nagle" <dann...@verizon.net> wrote in message
> news:2009041916364616807-dannagle@verizonnet...
>
>> I read your example. Your == is not pure. What are you demonstrating?
>
> That everything involved in executing the statement must be pure, not
> just one little part of it. You could have composed a statement such
> as:
>
> if(f(x)) continue
>
> if you wanted to restrict attention to pure function f, but in your
> case you unnecessarily inserted operator(==) and made no mention of
> it. In your subsequent snippet, you have exposure to operator(*),
> operator(+), and assignment(=).

Or, you could just assume, WLOG, that for simplicity,
I was describing a situation with *intrinsic* types,
since I didn't post any type definitions, let alone
define any overloaded operators.

> OK, so I guess I need to post
> another example, here everything is pure:

What I actually said was, >>> where the compiler can prove
the function result is not needed <<< to evaluate the expression,
the language in the standard that I was trying to explain
(apparently, not very well) allows, but does not require,
that a pure function reference may be elided.

Furthermore, at 7.1.5.2.4, paragraph 2,
"Once the interpretation of a numeric intrinsic operation is established,
the processor may evaluate any mathematically equivalent operation,
provided that the integrity of parenthesis is not violated."

And again, at 7.1.7, paragraph 1,
"It is not necessary for a processor to evaluate all of the operands
of an expression, or to evaluate entirely each operand, if the value
of the expression can be determined otherwise."

Notice how much ground is covered by "otherwise".

And again, at 7.1.7, paragraph 2,
"If a statement contains a function reference in a part of an expression
that need not be evaluated, all entities that would have become defined
in the execution of that reference become undefined at the completion
of evaluation of the expression containing the function reference."

You have, at best, discovered "processor-dependent approximation".

It is a cute example. I might use something like it when next
I teach floating point.

--
Cheers!

Dan Nagle

robin

unread,
Apr 19, 2009, 7:53:29 PM4/19/09
to
<nm...@cam.ac.uk> wrote in message news:gsf1d1$8a0$1...@soup.linux.pwf.cam.ac.uk...

> In article <2009041907085416807-dannagle@verizonnet>,
> Dan Nagle <dann...@verizon.net> wrote:
> >On 2009-04-18 19:31:33 -0400, "robin" <rob...@bigpond.com> said:
> >
> >>> Therefore, a continue can be used to signal the end
> >>> of the declaratives,
> >>
> >> It could be, but is innecessary.
> >> The next executable statement will do that.
> >
> >And it might lead to a confusing message if the first statement
> >has the name whose declaration is inconsistent.

Whether the first statement has an error or not,
it had nothing to do with a CONTINUE statement.
Sounds like you're still treating the compiler as if
it were Fortran 66.

> Or even a valid program in older Fortrans! An undeclared array
> with the first statement an assigment as the first executable
> statement is usually a valid statement function.

Using a modern compiler, an error message is delivered.

> >>> if( f( x) == 0.0 ) continue
> >>
> >> Fine, if you don't mind getting a warning message for that.
> >> Most people would be satisfied with
> >> waste = f(x),
> >> which requires fewer keystrokes and doesn't leave
> >> the reader wondering why on earth someone wrote
> >> the silly statement
> >> if (f(x) == 0.0) continue.
> >
> >But it does change the memory of the program,
> >which is the point I'm making.
>
> It MAY do so, but highly optimising compilers will eliminate it
> entirely.

They would be in error of they did.


robin

unread,
Apr 19, 2009, 7:53:29 PM4/19/09
to
"Dan Nagle" <dann...@verizon.net> wrote in message news:2009041907085416807-dannagle@verizonnet...

No, the point I made is that a function CANNOT be evaluated
without storing the result SOMEWHERE.


nm...@cam.ac.uk

unread,
Apr 20, 2009, 3:46:51 AM4/20/09
to
In article <ZPOGl.4826$y61....@news-server.bigpond.net.au>,

robin <rob...@bigpond.com> wrote:
>
>No, the point I made is that a function CANNOT be evaluated
>without storing the result SOMEWHERE.

You are wrong in both theory and practice.


Regards,
Nick Maclaren.

James Van Buskirk

unread,
Apr 20, 2009, 4:24:41 AM4/20/09
to
"Dan Nagle" <dann...@verizon.net> wrote in message
news:2009041918101716807-dannagle@verizonnet...

> Or, you could just assume, WLOG, that for simplicity,
> I was describing a situation with *intrinsic* types,
> since I didn't post any type definitions, let alone
> define any overloaded operators.

Where did I have any non-intrinsic type in my examples? Of course
I overloaded operators. That was the point I was trying to make,
along with perhaps overloading assignment. What does 'WLOG' stand
for?

>> C:\gfortran\clf\count_equal>ex2
>> total = 3.57627869E-06
>> 20*b = 2.38418579E-06

> You have, at best, discovered "processor-dependent approximation".

> It is a cute example. I might use something like it when next
> I teach floating point.

That seems cryptic to me. In my example b = epsilon(1.0) = 2.0**(-23)
= 1.1920928955078125e-7. 20*b should be 2.384185791015625e-6 and
total should be 30*b = 3.5762786865234375e-6. Both outputs seem to
be consistent with predictions to the last digit printed. The point
was that 0.0*f(x) /= 0 in my example so f(x) had to be evaluated to
determine what the nonzero value was.

Jugoslav Dujic

unread,
Apr 20, 2009, 6:38:41 AM4/20/09
to
Ron Shepard wrote:
> In article <2009041817485316807-dannagle@verizonnet>,
> Dan Nagle <dann...@verizon.net> wrote:
>
>> Hello,

>>
>> On 2009-04-18 17:03:56 -0400, Ron Shepard
>> <ron-s...@NOSPAM.comcast.net> said:
>>
>>> In article <2009041808554116807-dannagle@verizonnet>,

>>> Dan Nagle <dann...@verizon.net> wrote:
>>>> if( f( x) == 0.0 ) continue
>>> I wonder about this. Could a compiler optimize away the function
>>> reference in this case?
>> Oh, I suppose it's possible.
>
> I really meant to ask if a standard-conforming compiler could
> optimize away the function reference.

Oh, no, don't ask that question!

It should be put in (non-existent) clf's Frequently Asked
Questions, under "Questions that should not be asked under
any circumstances" :o).

--
Jugoslav
www.xeffort.com
Please reply to the newsgroup.
You can find my real e-mail on my home page above.

glen herrmannsfeldt

unread,
Apr 20, 2009, 7:29:50 AM4/20/09
to
Jugoslav Dujic <jdu...@yahoo.com> wrote:
(snip, someone wrote)


>> I really meant to ask if a standard-conforming compiler could
>> optimize away the function reference.

> Oh, no, don't ask that question!

> It should be put in (non-existent) clf's Frequently Asked
> Questions, under "Questions that should not be asked under
> any circumstances" :o).

Except possibly when one has a program that isn't working,
and that an important function might have been optimized out.

Also, C interoperability better not do it, as many C
functions have important side effects and the return
value is ignored. Then again, for many of those it is
best not to ignore the return value. (fclose being one
important case.)

-- glen

Dan Nagle

unread,
Apr 20, 2009, 7:48:54 AM4/20/09
to
Hello,

On 2009-04-20 04:24:41 -0400, "James Van Buskirk" <not_...@comcast.net> said:

> The point
> was that 0.0*f(x) /= 0 in my example so f(x) had to be evaluated to
> determine what the nonzero value was.

Please reread the quotations from the standard
you snipped.

--
Cheers!

Dan Nagle

robin

unread,
Apr 20, 2009, 10:54:18 AM4/20/09
to
"Dan Nagle" <dann...@verizon.net> wrote in message news:2009041911222575249-dannagle@verizonnet...

> Hello,
>
> On 2009-04-19 10:36:04 -0400, "robin" <rob...@bigpond.com> said:
>
> > At the very least, the value of the function is
> > stored in the variable nominated by the function.
>
> Most likely, in a register on most modern hardware.

RWIW.
The variable nominated by the function is the one
explicitly given in the RESULT clause, and in
its absence, the function name.

> > After that, the value may be returned on a stack
> > or in a register, depending on the compiler and hardware
> > available.
>
> Most likely, in a register on most modern hardware.
> The return value will certainly *not* be on the stack
> when the function has been in-lined.

I've yet to see that happen.

> > After that, the value is compared with zero, or tested
> > for zero (again, depending on the hardware or compiler).
>
> Most likely, an instruction to compare a register
> with zero is emitted, with no data memory traffic.

Hardware instructions actually exist for testing a value
for zero, without requiring the referencing of a specific zero.

If such an instruction isn't available on a particular processor,
then a specific compare with zero is required, probably from storage.


robin

unread,
Apr 20, 2009, 10:54:19 AM4/20/09
to
"Gary Scott" <garyl...@sbcglobal.net> wrote in message
news:gAGGl.2788$fD....@flpi145.ffdc.sbc.com...

> glen herrmannsfeldt wrote:
> > Dick Hendrickson <dick.hen...@att.net> wrote:
> >
> >>Ron Shepard wrote:
> >>
> >>>In article <2009041817485316807-dannagle@verizonnet>,
> >>> Dan Nagle <dann...@verizon.net> wrote:
> >
> >>>>On 2009-04-18 17:03:56 -0400, Ron Shepard
> >>>><ron-s...@NOSPAM.comcast.net> said:
> >
> >>>>>In article <2009041808554116807-dannagle@verizonnet>,
> >>>>> Dan Nagle <dann...@verizon.net> wrote:
> >>>>>
> >>>>>>if( f( x) == 0.0 ) continue
> >
> >>>>>I wonder about this. Could a compiler optimize
> >>>>>away the function reference in this case?
> >
> >>>>Oh, I suppose it's possible.
> >
> >>>I really meant to ask if a standard-conforming compiler could
> >>>optimize away the function reference.
> >
> >>The simple answer is "it's a matter of opinion".
> >
> > I believe that at the highest optimization levels one
> > should expect some things to not follow the strictest
> > interpretation of the standard. That is the tradeoff
> > for the speed of optimized code.
>
> Nooooooo! No matter how optimized, it is absolutely never acceptable to
> not achieve the global results that would be achieved if a function were
> completely executed. That includes side effects.

That's right. The compiler is broken if it doesn't do that.


robin

unread,
Apr 20, 2009, 10:54:21 AM4/20/09
to
"Dan Nagle" <dann...@verizon.net> wrote in message news:2009041911165516807-dannagle@verizonnet...

> Hello,
>
> On 2009-04-19 10:36:03 -0400, "robin" <rob...@bigpond.com> said:
>
> > "Ron Shepard" <ron-s...@NOSPAM.comcast.net> wrote in message
> > news:ron-shepard-F43F...@forte.easynews.com...
>
> >> I wonder about this. Could a compiler optimize away the function
> >> reference in this case?
> >
> > No.
>
> As Dick rather patiently explained, there are differing views
> on this point. In fact, different statements in the standard
> may be taken as leading to contradictory conclusions.

There is doubt whatsoever that the compiler is required to
execute the function in this case.

You are confusing this particular case with the case of
a pure function, where multiple occurrences with the
same values for argument(s) would return precisely
the same values. In that case, the compiler need only
evaluate the function once, and may substitute that
value for the other function calls, thus avoiding
re-evaluation, as in, for instance:-
z = f(x) + y + f(x)
where f(x) need be evaluated only once for pure function f.


Dan Nagle

unread,
Apr 20, 2009, 11:19:16 AM4/20/09
to
Hello,

On 2009-04-20 10:54:21 -0400, "robin" <rob...@bigpond.com> said:

> There is doubt whatsoever that the compiler is required to
> execute the function in this case.

<splork!>

Please reread my reply to James Van Buskirk where I not only cited
chapter and verse that the compiler need not execute a function,
but also the specific statement that the variables mentioned
in any side effects are specifically undefined.

Surprising? Perhaps.
Undesirable? Situation-dependent.
Allowed by the standard? Specifically.

The only difference of opinion is whether *other* statements
in the standard contradict those I cited to James Van Buskirk,
and, if so, under what circumstances.

robin's proof by assertion is wrong and tiresome.

--
Cheers!

Dan Nagle

Dick Hendrickson

unread,
Apr 20, 2009, 12:18:33 PM4/20/09
to
Your last statement isn't, in general, true. If z and y
are zero sized arrays f(x) doesn't need to be evaluated
at all, pure or not. This is explicitly stated in note
7.14. Further, if f(x) is NOT pure, it is absolutely
required to give the same result value on both invocations;
I don't think this requires two evaluations.

Dick Hendrickson

Dick Hendrickson

unread,
Apr 20, 2009, 12:57:27 PM4/20/09
to

But, the standard specifically allows function references to
be optimized away and even says what happens when they are.

From F2003:

"7.1.8.1 Evaluation of operands


It is not necessary for a processor to evaluate all of the
operands of an expression, or to evaluate entirely each operand,
if the value of the expression can be determined otherwise.

NOTE 7.14
This principle is most often applicable to logical expressions,
zero-sized arrays, and zero-length strings, but it applies to
all expressions.
For example, in evaluating the expression

X > Y .OR. L (Z)

where X, Y, and Z are real and L is a function of type logical,
the function reference L (Z) need not be evaluated if X is
greater than Y. Similarly, in the array expression

W (Z) + A

where A is of size zero and W is a function, the function
reference W(Z) need not be evaluated.
END NOTE 7.14

If a statement contains a function reference in a part of
an expression that need not be evaluated, all entities
that would have become defined in the execution of that
reference become undefined at the completion of evaluation
of the expression containing the function reference.

NOTE 7.15
In the examples in Note 7.14, if L or W defines its argument,
evaluation of the expressions under the specified conditions
causes Z to become undefined, no matter whether or not L(Z)
or W(Z) is evaluated."
END NOTE 7.15

The optimizer is free to optimize away function references.
And a standard conforming program can't rely on the side
effects of a function reference that MIGHT be thrown away.
There can be no doubt of that; the paragraph just before
note 7.15 is crystal clear (to me anyhow).

I think the real dispute comes down to simple statements
like
a = f(b)

must the compiler fully evaluate the expression "f(b)",
including performing the side-effect operations, or


"if the value of the expression can be determined

otherwise", can it merely use the result value?
Different people read it different ways. I think that
full evaluation is required if the result is required,
because that's how functions determine their results.
I think the "otherwise" was put in to allow function
evaluation to be skipped if the result value isn't
needed and should be understood in terms of optimizations
(as in the examples) that people understand. The
function is either completely evaluated, or it isn't.
To me, that's a useful definition. But, I can
understand how others see the "otherwise" much more
broadly.

Things are further confused by the discussion in chapter
14 of when IEEE errors signal. Specifically,

"In a sequence of statements ... if the execution of an
operation would cause an exception to signal but after
execution of the sequence no value of a variable depends
on the operation, whether the exception is signaling
is processor dependent. For example, when Y has the value
zero, whether the code
X = 1.0/Y
X = 3.0
signals IEEE DIVIDE BY ZERO is processor dependent."

Processors are, apparently, free to look at the general
context of a statement and decide what to do. This
makes something like
a = f(b)
a = 0.0
even more ambiguous.

The solution is to avoid side-effects as much as possible.
Unfortunately that leads to bad programming practice.
Functions need to be able to look at their arguments and
abort if there is a domain error. The original definition
of F required functions to be "pure" except it allowed
PRINT and STOP statements.

Dick Hendrickson


James Van Buskirk

unread,
Apr 20, 2009, 2:41:32 PM4/20/09
to
"Dick Hendrickson" <dick.hen...@att.net> wrote in message
news:XP1Hl.515$WR2...@bgtnsc04-news.ops.worldnet.att.net...

> NOTE 7.14
> This principle is most often applicable to logical expressions,
> zero-sized arrays, and zero-length strings, but it applies to
> all expressions.
> For example, in evaluating the expression

> X > Y .OR. L (Z)

> where X, Y, and Z are real and L is a function of type logical,
> the function reference L (Z) need not be evaluated if X is
> greater than Y. Similarly, in the array expression

> W (Z) + A

> where A is of size zero and W is a function, the function
> reference W(Z) need not be evaluated.
> END NOTE 7.14

That last expression is like shooting fish in a barrel:

C:\gfortran\clf\count_equal>type ex3.f90
module ops
implicit none
interface operator(+)
module procedure plus
end interface operator(+)
contains
pure function plus(x,y)
real, intent(in) :: x(:,:)
real, intent(in) :: y(:)
real plus(size(x,1),size(x,2))

plus = 2*x
end function plus

elemental function W(z)
real, intent(in) :: z
real W

W = z+1
end function W
end module ops

program ex3
use ops
implicit none
real Z(2,2)
real A(0)
character(20) fmt

Z = reshape((/ 1, 2, &
3, 4/), &
shape = shape(Z), order = (/2,1/))
A = 0 ! :)
write(fmt,'(a,i0,a)') '(',size(Z,2),'f5.1)'
write(*,'(a)') 'Z ='
write(*,fmt) Z
write(*,'(/a)') 'W (Z) + A ='
write(*,fmt) W (Z) + A
end program ex3

C:\gfortran\clf\count_equal>gfortran ex3.f90 -oex3

C:\gfortran\clf\count_equal>ex3
Z =
1.0 3.0
2.0 4.0

W (Z) + A =
4.0 8.0
6.0 10.0

Hopefully that note will be appropriately revised in the next
edition of the standard.

Dick Hendrickson

unread,
Apr 20, 2009, 5:13:36 PM4/20/09
to
I'd guess, even hope, not. Almost all of the examples can be
messed up by providing hidden derived type declarations
and/or operator overloads.

I don't see a good solution other than the assumption that
there isn't anything "unusual" in the unshown declarations.

Dick Hendrickson

James Van Buskirk

unread,
Apr 20, 2009, 6:08:22 PM4/20/09
to
"Dick Hendrickson" <dick.hen...@att.net> wrote in message
news:4A5Hl.890$WR2...@bgtnsc04-news.ops.worldnet.att.net...

> I'd guess, even hope, not. Almost all of the examples can be
> messed up by providing hidden derived type declarations
> and/or operator overloads.

> I don't see a good solution other than the assumption that
> there isn't anything "unusual" in the unshown declarations.

Well, the LOC in question and discussion in Note 7.14 seems to me to
carry a lot of group-think in that it's clear to the committee what
the underling assumptions are, but it's really fuzzy to me what the
implications of A being size zero (array of zero size, zero-length
string [array], user-defined type empty or with zero-size members --
in these last cases operator(+) must be overloaded) are supposed to
be. I suppose that the logic is supposed to be that A is a zero-sized
array and operator(+) is elemental so W(Z) either has the same
shape as A or is scalar. Then the output has shape already given
by A so you don't need to evaluate W(Z) to figure out the shape of
the expression.

But there are lots more possibilities to some readers. Maybe you
could add an appendix that has the boilerplate assumptions and
reference it in examples or snippets that need some of the
assumptions so that if you're trying to lead the reader through
some logical chain of thought he doesn't get distracted by the
fact that Fortran is pretty much only limited by the programmer's
imagination. One assumption would be that all operators are
standard intrinsic operators (so as to exclude extended intrinsic
operators). When an example violates any of the assumptions of the
appendix the exception could be specifically called out.

robin

unread,
Apr 21, 2009, 8:10:59 AM4/21/09
to
"Dan Nagle" <dann...@verizon.net> wrote in message news:2009042011191816807-dannagle@verizonnet...

> Hello,
>
> On 2009-04-20 10:54:21 -0400, "robin" <rob...@bigpond.com> said:
>
> > There is doubt whatsoever that the compiler is required to
> > execute the function in this case.
>
> <splork!>

If it speaks like a pig it must be a pig.


robin

unread,
Apr 21, 2009, 8:11:00 AM4/21/09
to
"Dick Hendrickson" <dick.hen...@att.net> wrote in message
news:tf1Hl.461$WR2...@bgtnsc04-news.ops.worldnet.att.net...

What? So now z and y are arrays?
They aren't. Had they been I would have said so.

robin

unread,
Apr 21, 2009, 8:10:58 AM4/21/09
to
"Dick Hendrickson" <dick.hen...@att.net> wrote in message
news:XP1Hl.515$WR2...@bgtnsc04-news.ops.worldnet.att.net...

Your extract does NOT apply to this specific example.
As I wrote in another post, you are confusing this case
with the case where multiple references to a given
pure function may be replaced with a single reference.

Your extract deals with logical expressions containing
more than one comparison/logical expression.
That does NOT apply here.
Does 0.0 in the above look like a zero extent array?
Does it look like a logical expression?
Will 0.0 signal division by zero?
Does the expression f(x) == 0.0 look like
a statement?


robin

unread,
Apr 21, 2009, 8:11:01 AM4/21/09
to
"Dan Nagle" <dann...@verizon.net> wrote in message news:2009042011191816807-dannagle@verizonnet...

> On 2009-04-20 10:54:21 -0400, "robin" <rob...@bigpond.com> said:
>
> > There is doubt whatsoever that the compiler is required to
> > execute the function in this case.
>

> Please reread my reply to James Van Buskirk where I not only cited
> chapter and verse that the compiler need not execute a function,

Please read what you posted a few days ago,
where you presented your own example
"if (f(x) == 0.0) continue"
and insisted that the function f(x) was executed.
In other words, you have now contradicted yourself. Proof:-

From: "Dan Nagle" <dann...@verizon.net>
Newsgroups: comp.lang.fortran
Sent: Saturday, April 18, 2009 10:55 PM

| Hello,
|
| On 2009-04-17 20:27:41 -0400, "robin" <rob...@bigpond.com> said:

| Also, a continue may be used to evaluate a function
| without storing the result anywhere, as in


|
| if( f( x) == 0.0 ) continue
|

| Note that a print statement containing the reference
| stores the result in the i/o buffers.

> but also the specific statement that the variables mentioned


> in any side effects are specifically undefined.
>
> Surprising? Perhaps.
> Undesirable? Situation-dependent.
> Allowed by the standard? Specifically.
>
> The only difference of opinion is whether *other* statements
> in the standard contradict those I cited to James Van Buskirk,
> and, if so, under what circumstances.
>
> robin's proof by assertion is wrong and tiresome.

The only tiresome person is yourself, who
contradicts what you have claimed, and who acts
like a pig to other posters.


Dan Nagle

unread,
Apr 21, 2009, 9:40:51 AM4/21/09
to
Hello,

This really is getting tiresome, but let's not end it
on a technical misstatement. :-(

On 2009-04-21 08:10:58 -0400, "robin" <rob...@bigpond.com> said:

> Does 0.0 in the above look like a zero extent array?

<splork!>

The two operands of a binary operator must be conformant.
A scalar, such as 0.0 above, is conformant
with any array (including a zero-sized one).

--
Cheers!

Dan Nagle

robin

unread,
Apr 22, 2009, 10:03:34 AM4/22/09
to
"Dan Nagle" <dann...@verizon.net> wrote in message news:2009042109405216807-dannagle@verizonnet...

> Hello,
>
> This really is getting tiresome, but let's not end it
> on a technical misstatement. :-(

The only one making technical mis-statements is YOU.
Given that x is scalar, and that function F returns a scalar,
you have contradicted yourself, and now won't admit it.
Now why is that?
So, instead, you create a smokescreen about
a non-existent "misstatement".

> On 2009-04-21 08:10:58 -0400, "robin" <rob...@bigpond.com> said:
>
> > Does 0.0 in the above look like a zero extent array?
>
> <splork!>

I see that you are still making a pig of yourself!

> The two operands of a binary operator must be conformant.
> A scalar, such as 0.0 above, is conformant
> with any array (including a zero-sized one).

That is irrelevant.


0 new messages