• Am I just up too late?

    From James Van Buskirk@21:1/5 to All on Thu Nov 10 03:07:28 2022
    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)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to James Van Buskirk on Thu Nov 10 02:55:30 2022
    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?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From FortranFan@21:1/5 to James Van Buskirk on Thu Nov 10 04:51:45 2022
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Lionel@21:1/5 to Steve Lionel on Thu Nov 10 10:54:34 2022
    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 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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Lionel@21:1/5 to James Van Buskirk on Thu Nov 10 10:52:38 2022
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From FortranFan@21:1/5 to Steve Lionel on Thu Nov 10 08:29:18 2022
    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,

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter Klausler US@21:1/5 to James Van Buskirk on Thu Nov 10 10:09:40 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to Steve Lionel on Thu Nov 10 11:55:05 2022
    "Steve Lionel" wrote in message news:jt4l26F57fbU1@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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Neil@21:1/5 to Peter Klausler US on Thu Nov 10 19:56:51 2022
    Peter Klausler US <pklausler@nvidia.com> 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.



    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to James Van Buskirk on Thu Nov 10 12:39:44 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From John@21:1/5 to All on Thu Nov 10 15:47:26 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to John on Thu Nov 10 16:43:00 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Lionel@21:1/5 to FortranFan on Thu Nov 10 20:06:25 2022
    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
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to All on Thu Nov 10 17:27:03 2022
    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?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to James Van Buskirk on Thu Nov 10 17:25:24 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Lionel@21:1/5 to All on Thu Nov 10 20:20:12 2022
    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.
    --
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to All on Fri Nov 11 01:58:29 2022
    "John" wrote in message news:c0721675-f40e-48ce-bdfd-84149438bb33n@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' :)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to Peter Klausler US on Fri Nov 11 06:46:36 2022
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robin Vowels@21:1/5 to James Van Buskirk on Fri Nov 11 06:37:40 2022
    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)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to All on Fri Nov 11 12:57:48 2022
    "Robin Vowels" wrote in message news:b3f1a258-d6ea-4593-a456-3161d08a4215n@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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Lionel@21:1/5 to All on Sat Nov 12 14:15:01 2022
    On 11/10/2022 8:27 PM, gah4 wrote:
    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?

    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.
    --
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)