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

Who says I need a result variable?

82 views
Skip to first unread message

Sean O'Donnelly

unread,
May 20, 2013, 2:52:32 PM5/20/13
to
Hello and a good evening,

I'm getting bizarre results with gcc 4.7 and Solaris Studio 12.2 on the
question (I didn't realize it was a question) whether a recursive function
needs an explicit result variable or not.

program gcc471
implicit none

integer :: x = 5

write (*,*) "factorial of ", x, " is ", fact(x)

contains
recursive integer function fact (n)
integer :: n

if (n == 0) then
fact = 1
else
fact = n * fact (n - 1)
end if
end function fact
end program gcc471

gives us:

gcc471.f95:15.23:

fact = n * fact (n - 1)
1
Error: 'fact' at (1) is the name of a recursive function and so refers to the result variable. Use an explicit RESULT variable for direct recursion (12.5.2.1)

First of all the copy I've got at 12.5.2.1 speaks about effects of intent.
The gfortran message probably should have pointed us to 12.5.2.2. From my
reading I've not got to specify a result variable and then my code must
work. I don't see any requirement to use a result variable.

Solaris Studio 12.2 tells me I'm using an ansi extension but it's a warning
not an error.

Who's right? Was there an update somewhere we've missed or have they gone a
bit too far on this? I don't read it as an extension, it's the way it must
work from all I can tell.

I've also got some nasty compile errors on a few pieces of code that use
recursive functions where Solaris Studio tells me my function name is a
result-name and therefore mustn't be used as an external function name,
although again from my reading if I don't specify a result-name then I
certainly must use the function name as the result variable.

ifort 2013.3 compiles the whole works without griping but I've not passed it
any particular switches to get it to warn about anything. Wouldn't it be
grand if all the compiler writers could agree!

What say you, gents?

Cheers,

Sean O'Donnelly

glen herrmannsfeldt

unread,
May 20, 2013, 3:10:57 PM5/20/13
to
Sean O'Donnelly <sodo...@yahoo.co.uk> wrote:

> I'm getting bizarre results with gcc 4.7 and Solaris Studio 12.2
> on the question (I didn't realize it was a question) whether
> a recursive function needs an explicit result variable or not.

As far as I know, you need it for direct recursion, but not
indirect recursion.

(snip)
> recursive integer function fact (n)
> integer :: n
> if (n == 0) then
> fact = 1
> else
> fact = n * fact (n - 1)
> end if
> end function fact

(snip)

> fact = n * fact (n - 1)
1
> Error: 'fact' at (1) is the name of a recursive function and so
> refers to the result variable. Use an explicit RESULT variable
> for direct recursion (12.5.2.1)

Traditionally, inside a function the function name is a variable,
or 'result variable'. In the case of indirect recursion (calling
a function that then calls you) that isn't a problem.

> First of all the copy I've got at 12.5.2.1 speaks about effects
> of intent. The gfortran message probably should have pointed
> us to 12.5.2.2. From my reading I've not got to specify a result
> variable and then my code must work. I don't see any requirement
> to use a result variable.

As well as I understand it, for direct recursion you need the
result variable different from the function name.

-- glen

Richard Maine

unread,
May 20, 2013, 4:00:51 PM5/20/13
to
Sean O'Donnelly <sodo...@yahoo.co.uk> wrote:

> recursive integer function fact (n)
> integer :: n
>
> if (n == 0) then
> fact = 1
> else
> fact = n * fact (n - 1)
> end if
> end function fact
...
> gcc471.f95:15.23:
>
> fact = n * fact (n - 1)
> 1
> Error: 'fact' at (1) is the name of a recursive function and so refers to
> the result variable. Use an explicit RESULT variable for direct
> recursion (12.5.2.1)

That's correct.

> First of all the copy I've got at 12.5.2.1 speaks about effects of intent.
> The gfortran message probably should have pointed us to 12.5.2.2.

It is probably citing the section of f2003. The section numbering there
is slightly different.

> From my
> reading I've not got to specify a result variable and then my code must
> work. I don't see any requirement to use a result variable.

From f95 12.5.2.2, since that's apparently where you are looking (and
that seems appropriate for an f95 compiler)

"If RESULT is not specified, the result variable is <function-name> and
all occurances of the function name in <execution-part> statements in
the scoping unit are references to the result variable."

You have an occurance of the function name in an <execution-part>,
therefore by the above, that is a reference to the result variable. But
it is not valid syntax for a reference to the result variable.
Therefore, your code is invalid. It is obviously intended to be a
recursive function reference instead.

That's exactly the kind of situation where you must specify RESULT.
Otherwise, there are cases where it can be ambiguous what is intended.
In your particular case, it isn't ambiguous, as the syntax is not valid
for a reference to the result variable. Allowing the unambiguous cases
is an extension to the standard.

> I've also got some nasty compile errors on a few pieces of code that use
> recursive functions where Solaris Studio tells me my function name is a
> result-name and therefore mustn't be used as an external function name,
> although again from my reading if I don't specify a result-name then I
> certainly must use the function name as the result variable.

I'd need to see actual code - not just a description of it.

--
Richard Maine
email: last name at domain . net
domain: summer-triangle

James Van Buskirk

unread,
May 20, 2013, 11:06:48 PM5/20/13
to
"Sean O'Donnelly" <sodo...@yahoo.co.uk> wrote in message
news:kndrdg$k14$1...@speranza.aioe.org...

> ifort 2013.3 compiles the whole works without griping but I've not passed
> it
> any particular switches to get it to warn about anything. Wouldn't it be
> grand if all the compiler writers could agree!

ifort is very liberal by default and in fact passes some features
that could only be coding errors in my coding style. When the
result variable is an array and all the dummy arguments are integers
and their number is the rank of the result variable, the code is
ambiguous. In fact, I think ifort may resolve the ambiguity
differently according as the function is declared with the
RECURSIVE keyword or the program is compiled with the /RECURSIVE
switch. You would have to check ifort docs or code up a test
program to be sure about this. Safest is to compile with standards
checking enforced and fix or at least understand and comment any
unintended extensions.

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


Sean O'Donnelly

unread,
May 21, 2013, 6:53:06 AM5/21/13
to
On 2013-05-20, Richard Maine <nos...@see.signature> wrote:
> Sean O'Donnelly <sodo...@yahoo.co.uk> wrote:
> That's correct.
>
>> First of all the copy I've got at 12.5.2.1 speaks about effects of intent.
>> The gfortran message probably should have pointed us to 12.5.2.2.
>
> It is probably citing the section of f2003. The section numbering there
> is slightly different.

It should be citing f95 and I should have written I specifed -std=f95
-pedantic -Wall on the compilations.

We've got a few dozen modules that have been working this way with an
earlier gfortran. The problems began when we recently upgraded to a newer
version and the old code built with all the warnings we could find starting
giving us errors.

> "If RESULT is not specified, the result variable is <function-name> and
> all occurances of the function name in <execution-part> statements in
> the scoping unit are references to the result variable."

I read this a half dozen times but refused to believe it. It seems a bit odd
to me the standard would call for this without specifying the semantics
clearly. What I gather from your answer and from going over the standard
again is with so-called "direct recursion" that is invoking the function
from within the function then it's required to specify a result-variable.
Otherwise you can have a recursive case where A calls B and B calls A and
then inside B the invocation of A isn't problematic according to the
standard and doesn't require a result variable. I say there shouldn't be two
ways to do this. That's sloppy and confusing and unbefitting Fortran! Give
us one simple way that always works. Yes I realize an explicit result-value
will always work but that is quite ugly and verbose when return (result)
would allow us not to specify a result-value and also prevent ambiguity in
all cases.

If I've gotten it this time then I think this could have been done a lot
better and it even seems like an effort to be different for the sake of
being different. I don't understand the point of a return statement when it
could have been used as a function to specify the return value thereby
getting us past this particular mess. It's unnecessarily complicated to have
to specify a result-value in some cases and not others.

recursive function ideal (x)
..

return (expression)
end function ideal

is a lot better, more intuitive etc. than

recursive function farfromideal (x) result (y)
..
..
if (bad-input) return
y = x(some_calculation)
end function farfromideal

This is something other languages have done correctly and simply. Why the
hoop-jumping specification of this?

Older gfortran doesn't have a problem with the code nor all of our other
code and ifort and other compilers we tried all support all or various bits
of this the way we coded it years ago. Maybe this is something the standards
team could look into. Having to code an explicit result-value some times and
not others and having the complexity of allowing the user to specify a
unique result-value as opposed to using the function-name which is quite a
bit more obvious, seems quite sloppy and unnecessary.

> You have an occurance of the function name in an <execution-part>,
> therefore by the above, that is a reference to the result variable. But
> it is not valid syntax for a reference to the result variable.
> Therefore, your code is invalid. It is obviously intended to be a
> recursive function reference instead.

Yes indeed, it's so obvious that several compilers did what we wanted with
it. Others, not all the time.

> That's exactly the kind of situation where you must specify RESULT.
> Otherwise, there are cases where it can be ambiguous what is intended.
> In your particular case, it isn't ambiguous, as the syntax is not valid
> for a reference to the result variable. Allowing the unambiguous cases
> is an extension to the standard.

I don't know what an ambiguous case would be but given several compilers do
understand the code it would seem they could flag ambiguous cases and accept
the vast majority of cases that I would expect are not ambiguous. Again this
is something C and other languages have managed to do fairly cleanly despite
their other sadistic characteristics. I didn't expect something like this to
be so crudely designed. And the implementors seem to agree with me to some
extent else they wouldn't have given us a way round it in some or all cases.

Cheers,

Sean

Sean O'Donnelly

unread,
May 21, 2013, 6:56:47 AM5/21/13
to
On 2013-05-21, James Van Buskirk <not_...@comcast.net> wrote:
> "Sean O'Donnelly" <sodo...@yahoo.co.uk> wrote in message
> news:kndrdg$k14$1...@speranza.aioe.org...
>
> ifort is very liberal by default and in fact passes some features
> that could only be coding errors in my coding style. When the
> result variable is an array and all the dummy arguments are integers
> and their number is the rank of the result variable, the code is
> ambiguous. In fact, I think ifort may resolve the ambiguity
> differently according as the function is declared with the
> RECURSIVE keyword or the program is compiled with the /RECURSIVE
> switch. You would have to check ifort docs or code up a test
> program to be sure about this. Safest is to compile with standards
> checking enforced and fix or at least understand and comment any
> unintended extensions.

Agree with you 100% James. Unfortunately although we used every warning
switch we could find we still got caught with our pants down when we tried a
newer version of gfortran. Our lesson learned, we're no longer going to
depend on one compiler for anything. When this happened we started
downloading everything we could find and tested with various flags under
various compilers and we'll make sure everything runs without warnings under
any of them to avoid this from happening again.

Thanks for the insight on ifort. Everything aside from older gfortran is new
to us. We're going over the doc now.

Maybe we need lint for Fortran.

Cheers,

Sean

Michel Olagnon

unread,
May 21, 2013, 8:13:56 AM5/21/13
to
Sean O'Donnelly �crivit :
> I don't know what an ambiguous case would be

recursive integer function fact (n)
integer :: n
dimension (n+1) :: fact
integer :: i

fact = 1
do i = 2, n+1
fact (1:i) = i * fact (i-1)
end do
end function fact

Richard Maine

unread,
May 21, 2013, 8:54:43 AM5/21/13
to
Sean O'Donnelly <sodo...@yahoo.co.uk> wrote:

> I say there shouldn't be two ways to do this.

And then suggests a 3rd way, namely

> That's sloppy and confusing and unbefitting Fortran! Give
> us one simple way that always works. Yes I realize an explicit result-value
> will always work but that is quite ugly and verbose when return (result)
> would allow us not to specify a result-value and also prevent ambiguity in
> all cases.

If you are suggesting that we disallow the existing ways, that ain't
gonna fly as that would invalidate every bit of existing code that used
functions. Compatibility with old code does indeed add lots of
complications. I would say that such compatibility is the source of some
of the messiest bits in the language. If you think this is messy, I'd
hate to show you some of the worst ones; they make this look trivial.

I could see some sense to the return(result) form, but without
disallowing the existing forms, that would add quite a lot of
complication on specifying how they mixed - far more complication than
the one you are complaining about. And disallowing the existing forms
ain't gonna happen.

I'd say that there actually is only one way now at some level. The only
distinction is in whether the result variable is named explicitly or
given a default name. Not having a default variable at all strikes me as
a much more significant difference.

If you don't like the multiple ways of doing this, take a look at how
many ways you can specify dimensions. It is quite a lot. I couldn't even
list them all without taking a while to make sure I hadn't overlooked
one.

> I don't know what an ambiguous case would be but given several compilers
> do understand the code it would seem they could flag ambiguous cases and
> accept the vast majority of cases that I would expect are not ambiguous.

Yes, as you note some do. However, it would be quite a bit *MORE*
complicated - not less - to specify precisely what cases were allowed
and what cases were not allowed. The standard tends to go with a pretty
broad brush on things like that specificically because it would add
complexity. There are many things like that. One example that comes up
here fairly often is the rules for making generics unambiguous. Those
rules disallow lots of things that are actually unambiguous, but don't
happen to fit the requirements of the standard. Those requirements are
intentionally simplified (but even the simple versions in the standard
are pretty messy).

glen herrmannsfeldt

unread,
May 21, 2013, 11:34:36 AM5/21/13
to
Sean O'Donnelly <sodo...@yahoo.co.uk> wrote:

(snip on recursion and result variables)

> It should be citing f95 and I should have written I specifed -std=f95
> -pedantic -Wall on the compilations.

> We've got a few dozen modules that have been working this way with
> an earlier gfortran. The problems began when we recently upgraded
> to a newer version and the old code built with all the warnings we
> could find starting giving us errors.

>> "If RESULT is not specified, the result variable is <function-name> and
>> all occurances of the function name in <execution-part> statements in
>> the scoping unit are references to the result variable."

> I read this a half dozen times but refused to believe it.
> It seems a bit odd to me the standard would call for this
> without specifying the semantics clearly. What I gather from
> your answer and from going over the standard again is with
> so-called "direct recursion" that is invoking the function
> from within the function then it's required to specify a
> result-variable.

The FUNCTION statement came with Fortran II, over 50 years ago.

Fortran didn't allow recursion until Fortran 90.

> Otherwise you can have a recursive case where A calls B and B
> calls A and then inside B the invocation of A isn't problematic
> according to the standard and doesn't require a result variable.
> I say there shouldn't be two ways to do this. That's sloppy and
> confusing and unbefitting Fortran!
> Give us one simple way that always works. Yes I realize an
> explicit result-value will always work but that is quite
> ugly and verbose when return (result) would allow us not to
> specify a result-value and also prevent ambiguity in all cases.

Yes, many other languages use the RETURN statement to specify the
return value. There are interesting features either way. I don't
suppose you ever use ENTRY, but it does make functions interesting.
The return variables for all the ENTRY names are EQUIVALENCEd.
If they are all the same type, then things work just fine.
If they have different types, then you have to be sure to use the
appropriate one.

PL/I also has ENTRY (maybe the only language other than Fortran
or some assemblers) and also the return value on the RETURN statement.
To allow for that, PL/I will convert the value on the RETURN statement
to the appropriate value for the ENTRY in use. (Actual conversion,
not EQUIVALENCE.)

Matlab and Octave use a return variable, but as far as I know it
isn't optional. (I never tried without one.) Matlab has many
features that seem inherited from Fortran, so that shouldn't be
too surprising.

> If I've gotten it this time then I think this could have been done
> a lot better and it even seems like an effort to be different for
> the sake of being different. I don't understand the point of a
> return statement when it could have been used as a function to
> specify the return value thereby getting us past this particular
> mess.

Note that Fortran did it first. At least all the languages that
I know of with return value on the RETURN statement were later
than Fortran. (About 1958 for Fortran II.)

-- glen

Walt Brainerd

unread,
May 21, 2013, 12:52:44 PM5/21/13
to
On 5/21/2013 5:54 AM, Richard Maine wrote:
. . .
>
> I could see some sense to the return(result) form,
. . .
>
As a matter of fact, this is exactly what I proposed
during the development of Fortran 90 when the recursive
ambiguity needed to be resolved. A reason given against
it was that some compilers allowed an extension to allow
an alternate return in a function. I thought this a
pretty terrible idea and it was not standard, so this
did not convince me, but obviously did convince others
to not accept it.


glen herrmannsfeldt

unread,
May 21, 2013, 4:16:17 PM5/21/13
to
I never liked it much. It came, as far as I know, from IBM Fortran IV.

But it seems to have been added in Fortran 90, is now obsolescent
but not yet deleted.

However, for IBM Fortran IV, and I believe Fortran 90 through 2008,
it is only allowed for SUBROUTINE and not FUNCTION.

So, there would have been no ambiguity, though maybe some confusion.

-- glen

Robin Vowels

unread,
May 22, 2013, 7:08:53 AM5/22/13
to
Take a look at page 369 of Fortran 90 Programming,
by Ellis, Phillips, and Lahey,
which is factorial by recursion.

Walt Brainerd

unread,
May 22, 2013, 2:45:24 PM5/22/13
to
On 5/21/2013 1:16 PM, glen herrmannsfeldt wrote:
> Walt Brainerd <wa...@swcp.com> wrote:
>> On 5/21/2013 5:54 AM, Richard Maine wrote:
>> . . .
>
>>> I could see some sense to the return(result) form,
>> . . .
>
>> As a matter of fact, this is exactly what I proposed
>> during the development of Fortran 90 when the recursive
>> ambiguity needed to be resolved. A reason given against
>> it was that some compilers allowed an extension to allow
>> an alternate return in a function. I thought this a
>> pretty terrible idea and it was not standard, so this
>> did not convince me, but obviously did convince others
>> to not accept it.
>
> I never liked it much. It came, as far as I know, from IBM Fortran IV.
>
> But it seems to have been added in Fortran 90, is now obsolescent
> but not yet deleted.

What you are talking about is alternate return for subroutines.
The objection was a possible conflict/confusion with alternate returns
for functions, which, as far as I know, have never been standard,
let alone obsolescent.

>
> However, for IBM Fortran IV, and I believe Fortran 90 through 2008,
> it is only allowed for SUBROUTINE and not FUNCTION.
>
> So, there would have been no ambiguity, though maybe some confusion.
>
> -- glen
>
Sorry, but some compilers (maybe not IBM--don't know) did allow
alternate return for functions as an extension to the standard.
0 new messages