How to reset static variables inside a function

Is there a way to reset variables declared as static in a function? The goal is to ensure that the function is not called with lingering values โ€‹โ€‹from an unbound call. For example, I have an opearting function on matrix columns.

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 the right way to "reset" a static variable? Are there other general ways to check for static variables? For example, I want to make sure that if the call is made with a new matrix with possible different sizes, the vector v changes and resets, etc. It seems to be easiest to call a function using 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 } 
+6
c initialization static reset
source share
5 answers

I would recommend turning it into a structure and writing a little helper function to control the semantics of what you are trying to do. It can return a buffer if the request matches its size, or create a new one on demand (and, if necessary, an old one).

0
source share

Instead, use the idempotent initialization function and global variables.

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 automatically, use __attribute__((constructor)) (for GCC) as follows:

 static void InitVars __attribute__((constructor)) (); 

However, it should be noted that if you need to do this, you should reconsider the use of in-function static variables and instead use the passed fresh ones that are returned / written and passed on to subsequent related calls.

+3
source share

One approach that I saw when the C module was imported into C ++ was to surround the entire module with the class wrapper and replace all static variables inside functions using unique names of global variables outside functions. I do not know what a good way to achieve a similar effect for projects related to multiple source files, although I would like to know if it exists. I have built-in system code in C that I mimic by adding some C ++ wrappers to VS2005. For example, I have I / O registers defined in such a way that something like TX1CON = 0x5C; Converts to something like IOMAP (0x251) .P = 0x5C; IOMAP is a property that sends "write 0x5C for address 0x251" to a hardware simulation program. This approach works well, but I cannot do a clean reset. Any ideas?

0
source share

An approach that can sometimes be useful if you need a "reset" method that can hit an unknown number of functions or modules should have a global counter, how many times this reset method has been called, and then each function or module includes code, for example:

  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-threaded contexts, if the initialization of static variables may depend on some global variables, you can replace "if" with "while"; in this case; memory locks may also be required in this case, although the exact requirements will vary depending on the operating environment.

In addition, an alternative template that can be useful on embedded systems is to have a global variable modules_initialized , which gets the global method reset 0, and then each module starts with something like:

  if (! atomic_bit_test_and_set32 (& modules_initialized, FOOBOZZ_MODULE_ID))
   {
     ... Initialize module FOOBOZZ ...
   }

This will require that there are no more than 32 module identifiers, and would require that they be uniquely distributed in some way, but some systems can handle this pretty well. For example, the linker may allow the definition of a โ€œdata sectionโ€ from address 0-31 of the address space, regardless of any other; if each module declares a single-byte variable in this address space, the linker can generate the corresponding addresses for these variables.

0
source share

you could build your function in such a way that if you call it null 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 just need to call the function to reset as follows:

 foo(); // internal values would then be reset 

Make sure that all your parameters for the function have default values; if, for example, you pass an option, then make sure that it has value = boost :: none as the default value

0
source share

All Articles