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

Confirmation of 77 standard interpretation for statement functions

1 view
Skip to first unread message

Mark R. Ludwig

unread,
Aug 24, 1993, 5:53:46 PM8/24/93
to
I would like some opinions about whether the following program
conforms to ANSI X3.9-1978:

PROGRAM JUNK
EXTERNAL FOO
CHARACTER*8 FOO
CHARACTER*8 STMTFA,STMTFB
INTEGER A
STMTFA(A) = FOO('A',A)
STMTFB(A) = FOO('B',A)
CALL BAR(STMTFA(1),STMTFB(2))
STOP
END
CHARACTER*(*) FUNCTION FOO(A,B)
CHARACTER*(*) A
INTEGER B
CHARACTER*4 C
WRITE(C,'(I4)') B
FOO = A // C
RETURN
END
SUBROUTINE BAR(A,B)
CHARACTER*(*) A,B
WRITE(*,*) A,' ',B
RETURN
END

The important part of all this, from my point of view, is that we have
multiple occurrences of the same external function appearing as actual
arguments to a subroutine via different statement functions.$$
--
INET: Mark-...@UAI.COM NIC: ML255 ICBM: USA; Lower Left Coast
"Anything worth doing in Japan is worth doing in a crowd." -- T. R. Reid

Richard Maine

unread,
Aug 24, 1993, 5:42:33 PM8/24/93
to
On Tue, 24 Aug 1993 21:53:46 GMT, m...@uai.com (Mark R. Ludwig) said:

Mark> I would like some opinions about whether the following program
Mark> conforms to ANSI X3.9-1978:
[sample omitted]

Yes, it conforms (unless I missed something, but it looks ok).

Mark> The important part of all this, from my point of view, is that we have
Mark> multiple occurrences of the same external function appearing as actual
Mark> arguments to a subroutine via different statement functions.

No you don't. The external function does not appear as an actual
argument. The value of the external function is evaluated and
used in computing the expressions in the actual arguments. Only
the resulting expression value is passed as an argument. It is
completely irrelevant that the evaluation of the expression happens
to involve external functions.

It is possible to pass external functions as arguments, but that
is a very different thing from passing an expression that involves
a function evaluation. When you pass such an expression, the
function is evaluated only once, for the specific values given
in the expression. When you pass an external function itself,
it is not evaluated at all during the call; just the address of
the function is passed.

--
--
Richard Maine
ma...@altair.dfrf.nasa.gov

Michael Lemke

unread,
Aug 25, 1993, 9:08:35 AM8/25/93
to
In article <MAINE.93A...@altair.dfrf.nasa.gov> ma...@altair.dfrf.nasa.gov (Richard Maine) writes:
>On Tue, 24 Aug 1993 21:53:46 GMT, m...@uai.com (Mark R. Ludwig) said:
>
>Mark> I would like some opinions about whether the following program
>Mark> conforms to ANSI X3.9-1978:
> [sample omitted]
>
>Yes, it conforms (unless I missed something, but it looks ok).
>

Well, I think you missed something:

CHARACTER*(*) FUNCTION FOO(A,B)
CHARACTER*(*) A

* ^^^^


INTEGER B
CHARACTER*4 C
WRITE(C,'(I4)') B
FOO = A // C

* ^^^^
RETURN
END

Isn't the underlined in violation of the standard? You can't append to
a string with length * if I remember some postings here correctly.

Michael
--
Michael Lemke
Astronomy, UT Austin, Texas
(mic...@io.as.utexas.edu or UTSPAN::UTADNX::IO::MICHAEL [SPAN])

Craig Burley

unread,
Aug 25, 1993, 7:54:56 AM8/25/93
to
In article <1993Aug25.1...@infodev.cam.ac.uk> mic...@mail.ast.cam.ac.uk (Michael Lemke) writes:

>Yes, it conforms (unless I missed something, but it looks ok).

Well, I think you missed something:

CHARACTER*(*) FUNCTION FOO(A,B)
CHARACTER*(*) A
* ^^^^
INTEGER B
CHARACTER*4 C
WRITE(C,'(I4)') B
FOO = A // C
* ^^^^
RETURN
END

Isn't the underlined in violation of the standard? You can't append to
a string with length * if I remember some postings here correctly.

No, it looks fine to me. You can have a *-length subexpression in
an expression involving concatenation (//) in an assignment statement --
but not as an actual argument. Reason being that FOO = A // C does not
require run-time heap allocation because it never needs more
space than is already allocated for the return value of FOO (by the
caller, typically); but CALL X(A//C) would require run-time allocation of
memory since the maximum length of the argument could not be calculated until
run time and no space would already be set aside to hold it.
--

James Craig Burley, Software Craftsperson bur...@gnu.ai.mit.edu
Member of the League for Programming Freedom (LPF) l...@uunet.uu.net

Craig Burley

unread,
Aug 25, 1993, 8:00:23 AM8/25/93
to

On Tue, 24 Aug 1993 21:53:46 GMT, m...@uai.com (Mark R. Ludwig) said:

Mark> I would like some opinions about whether the following program
Mark> conforms to ANSI X3.9-1978:
[sample omitted]

Yes, it conforms (unless I missed something, but it looks ok).

Mark> The important part of all this, from my point of view, is that we have
Mark> multiple occurrences of the same external function appearing as actual
Mark> arguments to a subroutine via different statement functions.

No you don't. The external function does not appear as an actual
argument. The value of the external function is evaluated and
used in computing the expressions in the actual arguments. Only
the resulting expression value is passed as an argument. It is
completely irrelevant that the evaluation of the expression happens
to involve external functions.

Well, not _completely_ irrelevant...here's the sample program again:

PROGRAM JUNK
EXTERNAL FOO
CHARACTER*8 FOO
CHARACTER*8 STMTFA,STMTFB
INTEGER A
STMTFA(A) = FOO('A',A)
STMTFB(A) = FOO('B',A)
CALL BAR(STMTFA(1),STMTFB(2))
STOP
END
CHARACTER*(*) FUNCTION FOO(A,B)
CHARACTER*(*) A
INTEGER B
CHARACTER*4 C
WRITE(C,'(I4)') B
FOO = A // C
RETURN
END
SUBROUTINE BAR(A,B)
CHARACTER*(*) A,B
WRITE(*,*) A,' ',B
RETURN
END

Now, delete subroutine BAR and replace CALL BAR(STMTFA(1),STMTFB(2)) with:

WRITE(*,*) STMTFA(1),STMTFB(2)

With these changes, the program is not standard-conforming, because during
execution of the new WRITE statement, FOO is invoked, which in turn
attempts to do I/O of some kind, and FORTRAN 77 does not allow nested I/O.

But I can't see anything wrong with the program as written. Maybe if the
poster actually spelled out what was apparently going wrong?

Mark R. Ludwig

unread,
Aug 25, 1993, 7:02:40 PM8/25/93
to
>>>>> "Craig" == Craig Burley <bur...@apple-gunkies.gnu.ai.mit.edu> writes:

Craig> But I can't see anything wrong with the program as written. Maybe if the
Craig> poster actually spelled out what was apparently going wrong?

As it turns out, the problem had nothing to do with what I thought it
did. The problem was with some hairy call chains involving more than
20 arguments, nested 3 or 4 deep, some of which are these statement
function evaluations. I made the mistake of trying to read the
standard regarding these things, and misinterpreted the part about not
being able to pass the statement function _itself_ as meaning one
could not pass an expression involving a statement function reference.
Then I started thinking about how the compiler allocates memory for
the return values from all the function calls in the actual argument
list, and confused myself even further.

The actual problem turned out to be a mismatch in some _other_ calls
earlier in the program. Too few arguments were being passed. The
manifestation was truly festive, because it somehow clobbered the
length descriptors for the other character arguments, so when they
were used later, their lengths were gigantic.

Maybe I have a candidate for that hairiest bug trawler after all....$$

Michael Lemke

unread,
Aug 25, 1993, 6:38:23 PM8/25/93
to
In article <BURLEY.93A...@apple-gunkies.gnu.ai.mit.edu> bur...@apple-gunkies.gnu.ai.mit.edu (Craig Burley) writes:
>In article <1993Aug25.1...@infodev.cam.ac.uk> mic...@mail.ast.cam.ac.uk (Michael Lemke) writes:
>
> >Yes, it conforms (unless I missed something, but it looks ok).
>
> Well, I think you missed something:
>
> CHARACTER*(*) FUNCTION FOO(A,B)
> CHARACTER*(*) A
> * ^^^^
> INTEGER B
> CHARACTER*4 C
> WRITE(C,'(I4)') B
> FOO = A // C
> * ^^^^
> RETURN
> END
>
> Isn't the underlined in violation of the standard? You can't append to
> a string with length * if I remember some postings here correctly.
>
>No, it looks fine to me. You can have a *-length subexpression in
>an expression involving concatenation (//) in an assignment statement --
>but not as an actual argument. Reason being that FOO = A // C does not
>require run-time heap allocation because it never needs more
>space than is already allocated for the return value of FOO (by the
>caller, typically); but CALL X(A//C) would require run-time allocation of
>memory since the maximum length of the argument could not be calculated until
>run time and no space would already be set aside to hold it.

Thanks, this makes much more sense now. So the code is just fine.
Sorry for my faulty posting.

Michael Stemper

unread,
Aug 25, 1993, 6:11:27 PM8/25/93
to
In article <MRL.93Au...@hp.uai.com>, m...@uai.com (Mark R. Ludwig) writes:
>I would like some opinions about whether the following program
>conforms to ANSI X3.9-1978:
>
> PROGRAM JUNK
> EXTERNAL FOO
> CHARACTER*8 FOO
> CHARACTER*8 STMTFA,STMTFB
> INTEGER A
> STMTFA(A) = FOO('A',A)
> STMTFB(A) = FOO('B',A)
> CALL BAR(STMTFA(1),STMTFB(2))

I would say that the last three statements are all invalid, as STMTFA
and STMTFB have not been defined as arrays.

There must be something that I'm overlooking here, because I'm sure
that somebody as sharp as Craig would have caught this...

--
#include <Standard_Disclaimer.h>
Michael F. Stemper
Power Systems Consultant
mste...@empros.com

Craig Burley

unread,
Aug 25, 1993, 10:37:48 PM8/25/93
to
In article <CCC5n...@empros.com> mste...@empros.com (Michael Stemper) writes:

In article <MRL.93Au...@hp.uai.com>, m...@uai.com (Mark R. Ludwig) writes:
>I would like some opinions about whether the following program
>conforms to ANSI X3.9-1978:
>
> PROGRAM JUNK
> EXTERNAL FOO
> CHARACTER*8 FOO
> CHARACTER*8 STMTFA,STMTFB
> INTEGER A
> STMTFA(A) = FOO('A',A)
> STMTFB(A) = FOO('B',A)
> CALL BAR(STMTFA(1),STMTFB(2))

I would say that the last three statements are all invalid, as STMTFA
and STMTFB have not been defined as arrays.

Indeed, which means that the first two of those three statements are
(interpreted by the compiler as) statement function definitions.

There must be something that I'm overlooking here, because I'm sure
that somebody as sharp as Craig would have caught this...

Well, comments in the code would certainly help. It's annoying for a
language definition to provide identical syntax for two kinds of
statements that have such widely different meaning. But such
annoyances weren't well-understood, apparently, when this aspect of
Fortran was designed. So comments like "DEFINE TWO STATEMENT FUNCTIONS",
even though typically overly verbose in more modern languages
(as in the C case of "i += 1; /* Add 1 to i. */"), can, when
thoughtfully used, help the human reader of Fortran code skim
stuff, and when abused, completely mislead any but the most cynical
and experienced Fortran hacker. :-)

Neat thing, though. As part of thinking about this post, I typed in
a sample program to GNU Fortran (my local in-development copy, as
yet unreleased), and it crashed! So, even though you might have missed
the statement-function angle, your post did trigger the discovery
of a g77 bug. (Gee, I hope it'll be easy to find and fix....)

0 new messages