Question about local variable of recursive subroutine

Question about local variable of recursive subroutine

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

 

12 帖子 / 0 全新
最新文章
如需更全面地了解编译器优化,请参阅优化注意事项

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

Thanks

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.

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

Best Reply

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

 

Steve

Quote:

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

 

Quote:

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

 

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

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.

Steve

Quote:

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

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.

Steve

Quote:

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

登陆并发表评论。