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

Am I just up too late?

132 views
Skip to first unread message

James Van Buskirk

unread,
Nov 10, 2022, 5:08:17 AM11/10/22
to
This seemed kind of weird to me. Am I just up too late?

D:\gfortran\james>type bug5.f90
recursive function bug5(x)
implicit none
character(*), intent(in) :: x
character(:), allocatable :: bug5
bug5 = x
if(bug5(1:1) == 'Z') bug5 = '_'//bug5
end function bug5

D:\gfortran\james>ifort /c bug5.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on
Inte
l(R) 64, Version 15.0.2.179 Build 20150121
Copyright (C) 1985-2015 Intel Corporation. All rights reserved.

D:\gfortran\james>gfortran -c bug5.f90
bug5.f90:6:11:

6 | if(bug5(1:1) == 'Z') bug5 = '_'//bug5
| 1
Error: 'bug5' at (1) is the name of a recursive function and so refers to
the re
sult variable. Use an explicit RESULT variable for direct recursion
(12.5.2.1)

gah4

unread,
Nov 10, 2022, 5:55:32 AM11/10/22
to
On Thursday, November 10, 2022 at 2:08:17 AM UTC-8, James Van Buskirk wrote:
> This seemed kind of weird to me. Am I just up too late?
>
> D:\gfortran\james>type bug5.f90
> recursive function bug5(x)
> implicit none
> character(*), intent(in) :: x
> character(:), allocatable :: bug5
> bug5 = x
> if(bug5(1:1) == 'Z') bug5 = '_'//bug5
> end function bug5

(snip)

> 6 | if(bug5(1:1) == 'Z') bug5 = '_'//bug5
> | 1
> Error: 'bug5' at (1) is the name of a recursive function and so refers to
> the re
> sult variable. Use an explicit RESULT variable for direct recursion
> (12.5.2.1)

Funniest bug message I can remember.

The whole idea of a result variable is that you can use it as a variable.

It looks like someone tried to catch the accidental use of recursion,
but got it wrong.

Does it work with a RESULT declaration?

FortranFan

unread,
Nov 10, 2022, 7:51:47 AM11/10/22
to
On Thursday, November 10, 2022 at 5:08:17 AM UTC-5, James Van Buskirk wrote:
> This seemed kind of weird to me. Am I just up too late?
> ..
> D:\gfortran\james>gfortran -c bug5.f90
> bug5.f90:6:11:
>
> 6 | if(bug5(1:1) == 'Z') bug5 = '_'//bug5
> | 1
> Error: 'bug5' at (1) is the name of a recursive function and so refers to
> the re
> sult variable. Use an explicit RESULT variable for direct recursion
> (12.5.2.1)

Perhaps the feedback from Fortran standard Editor and the discussion in this thread might help clarify whether the compiler might be wrong or right here:
https://groups.google.com/g/comp.lang.fortran/c/R7ztyouBwFw/m/FgJGEo-GDQAJ

Steve Lionel

unread,
Nov 10, 2022, 10:52:42 AM11/10/22
to
On 11/10/2022 5:07 AM, James Van Buskirk wrote:
> This seemed kind of weird to me. Am I just up too late?

You've stayed up far too long without updating - the compiler you're
using is 7.5 years old. Intel Fortran is now free, so no excuse not to
update.

D:\Projects>type james.f90
recursive function bug5(x)
implicit none
character(*), intent(in) :: x
character(:), allocatable :: bug5
bug5 = x
if(bug5(1:1) == 'Z') bug5 = '_'//bug5
end function bug5
D:\Projects>ifort/c james.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running
on Intel(R) 64, Version 2021.7.0 Build 20220726_000000
Copyright (C) 1985-2022 Intel Corporation. All rights reserved.
--
Steve Lionel
ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
Retired Intel Fortran developer/support
Email: firstname at firstnamelastname dot com
Twitter: @DoctorFortran
LinkedIn: https://www.linkedin.com/in/stevelionel
Blog: https://stevelionel.com/drfortran
WG5: https://wg5-fortran.org

Steve Lionel

unread,
Nov 10, 2022, 10:54:36 AM11/10/22
to
On 11/10/2022 10:52 AM, Steve Lionel wrote:
> You've stayed up far too long without updating - the compiler you're
> using is 7.5 years old. Intel Fortran is now free, so no excuse not to
> update.

Perhaps I woke up too soon - ifort still thinks the code is fine, it was
gfortran you were asking about. But my point about updating still holds.

FortranFan

unread,
Nov 10, 2022, 11:29:20 AM11/10/22
to
On Thursday, November 10, 2022 at 10:54:36 AM UTC-5, Steve Lionel wrote:

> On 11/10/2022 10:52 AM, Steve Lionel wrote:
> > You've stayed up far too long without updating - the compiler you're
> > using is 7.5 years old. Intel Fortran is now free, so no excuse not to
> > update.
> Perhaps I woke up too soon - ifort still thinks the code is fine, it was
> gfortran you were asking about. But my point about updating still holds.
> --

Steve,

Re: "Perhaps I woke up too soon - ifort still thinks the code is fine ..", by phrasing it this way, are you thinking the code is *not* fine? If so, what do you think is the case?

You may recall the previous discussion on a related topic at this forum a few months ago and the Malcolm Cohen feedback you fetched and posted - see the link upthread. Keeping that in mind, you think something is amiss with the code here? I fail to see that.

Perhaps you will also try out NAG compiler?

Thanks,

Peter Klausler US

unread,
Nov 10, 2022, 1:09:42 PM11/10/22
to
On Thursday, November 10, 2022 at 2:08:17 AM UTC-8, James Van Buskirk wrote:
> recursive function bug5(x)
> implicit none
> character(*), intent(in) :: x
> character(:), allocatable :: bug5
> bug5 = x
> if(bug5(1:1) == 'Z') bug5 = '_'//bug5
> end function bug5

This code is fine. If a compiler complains about it, please submit a bug report if the bug is in the most recent version of the compiler.

James Van Buskirk

unread,
Nov 10, 2022, 1:55:59 PM11/10/22
to
"Steve Lionel" wrote in message news:jt4l26...@mid.individual.net...

> You've stayed up far too long without updating - the compiler you're
> using is 7.5 years old. Intel Fortran is now free, so no excuse not to
> update.

I can always find excuses :) Intel Fortran and Atmel seem to like to
fight over Developer Studio, so every change can be problematic
and affect functionality that is only indirectly tied to it. But you have
to play with your Arduino, so what can you do?

Not to mention being sleep-deprived after my latest round of
working on my program, so I don't really have time and energy
to address any problems that may arise when updating, which
I assume would also involve updating Developer Studio.

But my old ifort does crash on my program whereas gfortran
doesn't if I work around its bugs like thinking it has two
different versions of C_PTR or not having a useful value of
the STATUS= argument to GET_COMMAND_ARGUMENT when
LEN(VALUE) == 0. When I get some spare time I intend to
upgrade ifort before investigating why the old version I have
crashes.

Neil

unread,
Nov 10, 2022, 2:56:54 PM11/10/22
to
Here is the result obtained using the NAG compiler:

pyb075000011:~> cat bug5.f90
recursive function bug5(x)
implicit none
character(*), intent(in) :: x
character(:), allocatable :: bug5
bug5 = x
if(bug5(1:1) == 'Z') bug5 = '_'//bug5
end function bug5

program test
interface
recursive function bug5(x)
character(*), intent(in) :: x
character(:), allocatable :: bug5
end function bug5
end interface
write(*,*)bug5("Arthur")
write(*,*)bug5("Zaphod")
end program test

pyb075000011:~> nagfor -C=all -C=undefined -gline -info -nan -O0 -strict95 -u -v bug5.f90
NAG Fortran Compiler Release 7.1(Hanzomon) Build 7101
bug5.f90:
[NAG Fortran Compiler normal termination]
Loading...

pyb075000011:~> ./a.out
Arthur
_Zaphod

gah4

unread,
Nov 10, 2022, 3:39:46 PM11/10/22
to
On Thursday, November 10, 2022 at 2:08:17 AM UTC-8, James Van Buskirk wrote:

(snip)

> recursive function bug5(x)
> implicit none
> character(*), intent(in) :: x
> character(:), allocatable :: bug5
> bug5 = x
> if(bug5(1:1) == 'Z') bug5 = '_'//bug5
> end function bug5

There is no function call form where arguments have a : in them.

This does remind me, which version of the standard added allocate
on assignment for the length of CHARACTER variables?

I thought that was later than for arrays, but might have forgotten.

This test on Z reminds me that not so long ago, I was working with
IBM's ECAP, from the late Fortran II and early Fortran IV days.

It seems that the version I have is for a compiler that only allows
for 5 character variable names. (Part of the BASIC Fortran standard.)

There are WRITE statements that print out values, including the
original name, though.

In any case, they took all the six letter names, removed the center two
characters and replaced them with a Z. It seems that resulted in
unique enough names, but they are funny to read.


John

unread,
Nov 10, 2022, 6:47:28 PM11/10/22
to

Perhaps I have been up too long myself. I thought the RESULT() syntax was
added specifically to allow unambigious recursion and would be the answer
as if bug5() took no parameters what would "//bug5" mean, as () is often optional,
or it it took an integer argument but returned an integer array is bug5(3) a reference
to an element or a recursive call to the procedure, and so on. I would have used RESULT(ANSWER)
on any recursive procedure ( I actually see no recursion here, by the way (?) ; but perhaps that is
just an old habit because of bugs I hit in the past as I was surprised it was required. Although I was
really surprised that recursive was becoming the default and wondered why that did not break a lot
things. Anyway, interesting. Some old assumptions I had are apparently wrong; bug using RESULT(ANSWER)
gfortran quit complaining. Gives me a few things to look back up and reread.

recursive function bug5(x) result(answer)
implicit none
character(*), intent(in) :: x
character(:), allocatable :: answer
answer = x
if(answer(1:1) == 'Z') answer = '_'//answer
end function bug5

recursive program test
interface
function bug5(x)
character(*), intent(in) :: x
character(:), allocatable :: bug5
end function bug5
end interface
write(*,*)bug5("Arthur")
write(*,*)bug5("Zaphod")
end program test

Maybe a gfortran bug is what made me form that habit.

gah4

unread,
Nov 10, 2022, 7:43:02 PM11/10/22
to
On Thursday, November 10, 2022 at 3:47:28 PM UTC-8, John wrote:
> Perhaps I have been up too long myself. I thought the RESULT() syntax was
> added specifically to allow unambigious recursion and would be the answer
> as if bug5() took no parameters what would "//bug5" mean, as () is often optional,

Yes it is supposed to be unambiguous. Without RESULT, the name is always
the result variable. That is why the message is so funny!

It assumes something that can't be true, and then gives an error.

Now, I could see a warning, but it has to assume the result variable
in any case.

It might be that so few use the RECURSIVE attribute, that it hasn't
been tested enough.






Steve Lionel

unread,
Nov 10, 2022, 8:06:29 PM11/10/22
to
On 11/10/2022 11:29 AM, FortranFan wrote:
> Steve,
>
> Re: "Perhaps I woke up too soon - ifort still thinks the code is fine ..", by phrasing it this way, are you thinking the code is*not* fine? If so, what do you think is the case?
>
> You may recall the previous discussion on a related topic at this forum a few months ago and the Malcolm Cohen feedback you fetched and posted - see the link upthread. Keeping that in mind, you think something is amiss with the code here? I fail to see that.
>
> Perhaps you will also try out NAG compiler?

The code is fine - I did not intend to imply otherwise. NAG Fortran also
accepts it.

Steve Lionel

unread,
Nov 10, 2022, 8:20:16 PM11/10/22
to
On 11/10/2022 3:39 PM, gah4 wrote:
> This does remind me, which version of the standard added allocate
> on assignment for the length of CHARACTER variables?

Deferred-length character allocatables were added in F2003.

gah4

unread,
Nov 10, 2022, 8:25:26 PM11/10/22
to
On Thursday, November 10, 2022 at 2:08:17 AM UTC-8, James Van Buskirk wrote:

(snip)

> recursive function bug5(x)
> implicit none
> character(*), intent(in) :: x
> character(:), allocatable :: bug5
> bug5 = x
> if(bug5(1:1) == 'Z') bug5 = '_'//bug5
> end function bug5

Agreeing that this should be fine, I suspect I would have
used x(1:1) instead of bug5(1:1).

Three fewer characters to type.

Reminds me that, not too many years ago, in explaining
something to someone, I used "less than".
I was then corrected, and told it should be "fewer then"
for discrete values.

I quickly figure out that couldn't be right, as Fortran does
not have a .FT. operator. Less than has to also work for
integer values.

OK, three less characters to type.


gah4

unread,
Nov 10, 2022, 8:27:05 PM11/10/22
to
On Thursday, November 10, 2022 at 5:20:16 PM UTC-8, Steve Lionel wrote:

(I wrote)

> > This does remind me, which version of the standard added allocate
> > on assignment for the length of CHARACTER variables?

> Deferred-length character allocatables were added in F2003.

Just to be sure, also allocate on assignment at the same time?


James Van Buskirk

unread,
Nov 11, 2022, 3:59:23 AM11/11/22
to
"John" wrote in message
news:c0721675-f40e-48ce...@googlegroups.com...

> ( I actually see no recursion here, by the way (?)

The recursion happened because the function was called
in a multithreaded context. Before RECURSIVE was made
the default, local variables could be given the SAVE
attribute by the compiler if it wanted to, like in F77.
Declaring a procedure as RECURSIVE means that other
instances of the procedure in other threads would not
tromp on its unSAVEd local variables.

My workaround was, as you and others suggested,
to use a RESULT variable (but I called it 'bug5' :)

Robin Vowels

unread,
Nov 11, 2022, 9:37:42 AM11/11/22
to
On Thursday, November 10, 2022 at 9:08:17 PM UTC+11, James Van Buskirk wrote:
> This seemed kind of weird to me. Am I just up too late?
>
> D:\gfortran\james>type bug5.f90
> recursive function bug5(x)
> implicit none
> character(*), intent(in) :: x
> character(:), allocatable :: bug5
> bug5 = x
> if(bug5(1:1) == 'Z') bug5 = '_'//bug5
> end function bug5

You have written a recursive function, bug5.
Then in the IF statement, you ask for the value of BUG5. That's a recursive call.
Then in the true part of the statement, you again ask for the value of BUG5.
That requires another recursive call.

> D:\gfortran\james>ifort /c bug5.f90
> Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on
> Inte
> l(R) 64, Version 15.0.2.179 Build 20150121
> Copyright (C) 1985-2015 Intel Corporation. All rights reserved.
>
> D:\gfortran\james>gfortran -c bug5.f90
> bug5.f90:6:11:
>
> 6 | if(bug5(1:1) == 'Z') bug5 = '_'//bug5
> | 1
> Error: 'bug5' 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)

Robin Vowels

unread,
Nov 11, 2022, 9:46:38 AM11/11/22
to
.
If the word "recursive" had been omitted, it might have been fine;
the name BUG5 in the IF statement (in 2 places) would have been treated as
if it were an ordinary variable.
With the word "recursive" present, any occurrence of the word BUG5 in an expression
constitutes a recursive reference.

James Van Buskirk

unread,
Nov 11, 2022, 2:58:47 PM11/11/22
to
"Robin Vowels" wrote in message
news:b3f1a258-d6ea-4593...@googlegroups.com...

> On Friday, November 11, 2022 at 5:09:42 AM UTC+11, Peter Klausler US
> wrote:
> > On Thursday, November 10, 2022 at 2:08:17 AM UTC-8, James Van Buskirk
> > wrote:
> > > recursive function bug5(x)
> > > implicit none
> > > character(*), intent(in) :: x
> > > character(:), allocatable :: bug5
> > > bug5 = x
> > > if(bug5(1:1) == 'Z') bug5 = '_'//bug5
> > > end function bug5
> > This code is fine. If a compiler complains about it, please submit a bug
> > report if the bug is in the most recent version of the compiler.

> If the word "recursive" had been omitted, it might have been fine;
> the name BUG5 in the IF statement (in 2 places) would have been treated as
> if it were an ordinary variable.
> With the word "recursive" present, any occurrence of the word BUG5 in an
> expression
> constitutes a recursive reference.

From N2137, section 15.6.2.2:

If RESULT appears, the name of the function result of the function
is result-name and all occurrences of the function name in
execution-part statements in its scope refer to the function itself.
If RESULT does not appear, the name of the function result is
function-name and all occurrences of the function name in
execution-part statements in its scope are references to the
function result.

Steve Lionel

unread,
Nov 12, 2022, 2:15:04 PM11/12/22
to
Yes. When ifort first implemented deferred-length allocatables,
(re)allocation was not the default, as it was for arrays. I argued,
successfully before release, that this was a new feature and
compatibility with F90 was not required. Of course, now, ifort does the
allocate-on-assignment by default for arrays too.
0 new messages