# Clear a variable in fortran subroutine

## Main Question or Discussion Point

Hello,

I am trying to figure out how to clear a variable inside a subroutine from a calling function. The variable in the subroutine acts as a persistent(MATLAB) or static(C), but once in so many calls I want it to be reset to empty as if the subroutine is being called for the first time.

I can do this in MATLAB by calling the subroutine in a for loop. On the kth run, clear functions, call subroutine. The subroutine is now called with persistent variables cleared:

function y = foo(a)
n = 6;
k = 3;
for ii = 1:n
if ii == k
clear functions​
end
x(ii) = subfoo(a)​
end

Any help would be appreciated,

Candice

Related Programming and Computer Science News on Phys.org
Go ahead and post your Fortran code to get a better understanding of what you mean and are trying to do.

Other than that, you could write your function in a way that takes an additional argument, say, of logical type...if it is set to true, the function behaves as if it was the very first time is being called; if it is false, it does not.

Alternately, you could write a module with its set of variables and a couple of functions, one you call to perform something, the other one to reset variables to their initial values.

Hi gsal, thank you for your response.

Unfortunately, I cannot post my code, and I cannot modify the subroutine in any way (I am unit testing it).

If I write a module with its set of variables to reset to initial values, can I call that from my parent function? Or are those variable names only pointing to the correct place in memory while in the subroutine? I cannot reset the variables inside my subroutine as I cannot modify my subroutine.

I was thinking something like this
Code:
module bla
integer :: b = 0
contains
subroutine bla_reset()
b = 0
end subroutine bla_reset()
function bla_do()
b = b + 3
return b
end function bla_do()
end module bla
Then, in reference to your matlab code that you posted above, instead of "clear functions" you do "call bla_reset()" and instead of "x(ii) = subfoo(a)" you do "x(ii) = bla_do(a).

I was thinking something like this
Code:
module bla
integer :: b = 0
contains
subroutine bla_reset()
b = 0
end subroutine bla_reset()
function bla_do()
b = b + 3
return b
end function bla_do()
end module bla
Then, in reference to your matlab code that you posted above, instead of "clear functions" you do "call bla_reset()" and instead of "x(ii) = subfoo(a)" you do "x(ii) = bla_do(a).
will this work if the variable b belongs solely to (and is not returned by) bla_do? In my subroutine (bla_do), it is declared equal to 1. Like this:
Code:
module bla
integer  b
contains
subroutine bla_reset()
b = 1
end subroutine bla_reset()
function bla_do()
integer  b \1\
b = b + 3
end function bla_do()
end module bla
I'm learning on-the-fly how fortran's "workspace" (for lack of a better term) is available between functions.

I would remove the integer declaration inside bla_do...otherwise, it looks like you keep re-initailizing it every call...instead, let it keep increasing by 3 every time you call ...then, once in a while, you call bla_reset...

...if I understand what you are trying to do

Because I am testing bla_do(), I can't modify it. So I can't remove the declaration in the beginning. But I am certain that the way the fortran is set up in my real code, that variable is declared equal to 1 only on the first iteration ; thereafter it takes on the last value when the function was called previously.

My intention, is to (at some point inside a forloop that calls bla_do) reset that variable so when bla_do() is called, it acts as it would the first time it is called. It's a weird thing to need; it is an artifact of testing bla_do rather than developing.

Code:
module bla
integer  b
for i = 1:100
if i = 50
CALL bla_reset() //reset b back to 1 at iteration 50
endif
CALL bla_do() // do whatever blah does
end module bla

subroutine bla_reset()
b = 1
end subroutine bla_reset()
subroutine  bla_do()
integer  b \1\ //this syntax should set b = 1 only on first call; otherwise b retains value from last call (or hopefully from when it is set to 1 in bla_reset)
b = b + 3
end subroutine bla_do()
I'm curious that b can be reset in the separate subroutine bla_reset and it is felt by bla_do, even when bla_reset and bla_do don't have b as input or output arguments.

This thing about bla_reset and bla_do not needing to declare b, yet being aware of it, is a benefit of using modules...but I see in your latest post that you have messed things up :-(

First, you have kicked bla_reset and bla_do out of the module...you should go back and review how I did it...inside the module but after the "contains" keyword.

Also, a module is not a main program...you should take the code you have in the module (latest post) and make it a separate main procedure, like
Code:
module bla
.
.
.
end module bla

program main
use bla
for i = 1:100
if i = 50
CALL bla_reset() //reset b back to 1 at iteration 50
endif
CALL bla_do() // do whatever bla does
end program main

Ah, I see. Unfortunately bla_do() is a subroutine, and I can't touch it (I must view it as a black box), so I can't change it into a module. I think because of this problem, I can't use the method you are suggesting.

FactChecker