Is there a way to reset variables declared as static within a function? The goal is to make sure that the function is not called with lingering values from an unrelated call. For example, I have a function opearting on columns of a matrix.
int foo(matrix *A, int colnum, int rownum){
static int whichColumn;
static int *v; //vector of length A->nrows
if (column != whichColumn){
memset(v,0,size);
whichColumn = which;
}
//do other things
}
The function is called n times, once for each column. Is this a proper way of "re-setting" the static variable? Are there other general fool-proof ways of resetting static variables? For example, I want to make sure that if the call is made with a new matrix with possibly different dimensions then the vector v is resized and zeroed etc. It seems the easiest way may be to call the function with a NULL pointer:
int foo(matrix *A, int colnum, int rownum){
static int whichColumn;
static int *v; //vector of length A->nrows
if (A == NULL){
FREE(v);
whichColumn = 0;
}
//do other things
}
I'd recommend turning it into a struct and writing a small helper function for managing the semantics of what you're trying to do. It could return the buffer if the request is appropriate for its size, or create a new one on demand (and free the old one) if necessary.
Use an idempotent initializer function and global variables instead.
For example:
int foo;
int *m = NULL;
static void InitVars() {
foo = 0;
if (m != NULL) {
free(m);
}
m = malloc(sizeof(int)*5);
memset(m, 0, sizeof(int)*5);
}
If your initializer is really idempotent, you can call it again to reset the variables.
If you need this to be called automagically, use __attribute__((constructor))
(for GCC) like so:
static void InitVars __attribute__((constructor)) ();
However, you should note that if you need to do this, you should reconsider using in-function static
variables and instead use passed-in fresh ones that are returned/written and passed to subsequent related calls.
One approach I've seen used when a C module was imported to C++ was to surround the whole module with a class wrapper, and replace all static variables inside functions with uniquely-named "global" varaibles outside the functions. I don't know any good way to achieve a similar effect for projects involving multiple source files, though I'd like to know if one exists. I have some embedded system code in C, which I simulate by adding some C++ wrappers in VS2005. For example, I have I/O registers defined so that something like TX1CON = 0x5C; would translate into something like IOMAP(0x251).P = 0x5C; IOMAP is a property which would send "write 0x5C to address 0x251" to a hardware-simulation program. This approach works well, but I can't do a clean reset. Any ideas?
An approach which can sometimes be helpful if one needs a "reset" method which can hit an unknown number of functions or modules is to have a global counter for how many times that reset method has been called, and then have each function or module include code like:
extern unsigned long global_reset_count;
void do_something(int whatever)
{
static ... this, that, the other, etc. ...;
static unsigned long my_reset_count;
if (my_reset_count != global_reset_count)
{
my_reset_count = global_reset_count;
... initialize this, that, the other, etc ...
}
}
In some multi-threading contexts, if the initialization of the static variables may depend upon some global variables, one may wish to replace the "if" with a "while"; in such a case; memory barriers may also be needed in such a case, though the exact requirements would vary depending upon the operating environment.
Also, an alternative pattern that may be useful within embedded systems would be to have a modules_initialized
global variable which gets set to 0 by the global reset method, and then have each module start with something like:
if (!atomic_bit_test_and_set32(&modules_initialized, FOOBOZZ_MODULE_ID))
{
... Initialize module FOOBOZZ ...
}
This would require that there be no more than 32 module ID's, and would require that they be uniquely allocated somehow, but some systems can handle that pretty nicely. For example, a linker may allow one to define a "data section" from address 0-31 of an address space independent from any other; if each module declares a single-byte variable within that address space, the linker could generate the appropriate addresses for those variables.
you could build your function in such a way that if you call it with zero parameters, then it will reset its internal static variables
here is an example :
int foo(matrix *A = NULL, int colnum = 0, int rownum = 0)
{
static int whichColumn;
static int *v; //vector of length A->nrows
if (A == NULL){
FREE(v);
whichColumn = 0;
}
//do other things
}
You actually just have to call function to reset like this:
foo(); // internal values would then be reset
Make sure that all your parameters to the function has default values, if for example you pass an optional, then make sure it has = boost::none as default value