Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29426 Discussions

Question about local variable of recursive subroutine

Zhanghong_T_
Novice
1,571 Views

Dear all,

For the following code, the compiler will show error #8000 if I use /warn:interfaces option. Could anyone tell me the problem of the code?

After disabled this option, the running result is not what I expected. I wish the results are every subroutine's local value i, but now every display is 11. Could anyone help me to take a look at the problem?

 

Thanks,

Zhanghong Tang

 

 

    subroutine test_recursive(i)
    implicit none
    integer::i
    i=i+1
    if(i<=10)call test_recursive(i)
    print *,i
    end subroutine

    program testrecursive

    implicit none

    ! Variables
    integer::i=0
    ! Body of testrecursive
    call test_recursive(i)
    end program testrecursive

 

0 Kudos
1 Solution
Steven_L_Intel1
Employee
1,571 Views

Or do this instead:

 recursive subroutine test_recursive(i)
    implicit none
    integer::i
    if(i<=10)call test_recursive(i+1)
    print *,i
    end subroutine

 

View solution in original post

0 Kudos
11 Replies
Zhanghong_T_
Novice
1,571 Views

Oh sorry, the first problem is solved. I forgot to add keyword  'RECURSIVE'. How to solve my second problem?

Thanks

0 Kudos
JVanB
Valued Contributor II
1,571 Views

Since i is passed by reference, there is only one value of i, not one per instance.  If you wish to create per-instance values for i, declare it as being passed by value and makes its interface explicit to program testrecursive.

0 Kudos
DavidWhite
Valued Contributor II
1,571 Views

The print statement needs to be before the recursive call to the subroutine.  You only ever get to the print statement after the last call.

David

0 Kudos
Steven_L_Intel1
Employee
1,572 Views

Or do this instead:

 recursive subroutine test_recursive(i)
    implicit none
    integer::i
    if(i<=10)call test_recursive(i+1)
    print *,i
    end subroutine

 

0 Kudos
Zhanghong_T_
Novice
1,571 Views

David White wrote:

 

The print statement needs to be before the recursive call to the subroutine.  You only ever get to the print statement after the last call.

 

David

Hi David,

Thanks for your kindly reply. The code I put here is the simplest. The real code need the print statement be after the last call. I wish the first print is the last calling's i value, the second print is the previous calling's i value, and so on. Just like the push and pop of stack. How to modify the code?

Thanks

 

0 Kudos
Zhanghong_T_
Novice
1,571 Views

Steve Lionel (Intel) wrote:

Or do this instead:

 recursive subroutine test_recursive(i)
    implicit none
    integer::i
    if(i<=10)call test_recursive(i+1)
    print *,i
    end subroutine

 

Dear Steve,

Thank you very much for your kindly reply. The output is just what I needed.

However, I need the increase of i be happened in the subroutine instead of during calling. I require this because every time the increase could be different. Is it possible to do so?

 

Thanks

 

0 Kudos
IanH
Honored Contributor III
1,571 Views

Won't some of these code samples result in recursive IO?

0 Kudos
Steven_L_Intel1
Employee
1,571 Views

Ian, recursive I/O? No - none of the I/O statements invoke the function.

If you need the updated copy of i locally do it this way:

recursive subroutine test_recursive(i)
   implicit none
   integer::i, local_i
   local_i = i + 1
   if(i<=10)call test_recursive(local_i)
   print *,local_i
   end subroutine

Note that this doesn't allow the call to test_recursive to modify i, but you said you didn't want that.

0 Kudos
Zhanghong_T_
Novice
1,571 Views

Steve Lionel (Intel) wrote:

Ian, recursive I/O? No - none of the I/O statements invoke the function.

If you need the updated copy of i locally do it this way:

recursive subroutine test_recursive(i)
   implicit none
   integer::i, local_i
   local_i = i + 1
   if(i<=10)call test_recursive(local_i)
   print *,local_i
   end subroutine

Note that this doesn't allow the call to test_recursive to modify i, but you said you didn't want that.

Dear Steve,

Thank you very much for your kindly reply. I was confused the local parameters and passed parameters. I think the parameters should be recovered to original value when the function is back from the recursive calling, but I don't know the change of passed parameters can't be recovered.

I have modified my code to let it work on this rule.

Thanks

0 Kudos
Steven_L_Intel1
Employee
1,571 Views

There are two ways to prevent the called procedure from changing the variable you pass to it. One is to add the VALUE attribute in the interface to the procedure, as suggested earlier, but this requires an explicit interface. Another is to pass the variable enclosed in parentheses, making it an expression. Both have the same effect.

0 Kudos
Zhanghong_T_
Novice
1,571 Views

Steve Lionel (Intel) wrote:

There are two ways to prevent the called procedure from changing the variable you pass to it. One is to add the VALUE attribute in the interface to the procedure, as suggested earlier, but this requires an explicit interface. Another is to pass the variable enclosed in parentheses, making it an expression. Both have the same effect.

Dear Steve,

Thank you very much for your kindly reply. I got it now.

Thanks,

Zhanghong Tang

0 Kudos
Reply