Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a C program, is it possible to reset all global variables to default vaues?

I have a legacy C Linux application that I need to reuse . This application uses a lot of global variables. I want to reuse this application's main method and invoke that in a loop. I have found that when I call the main method( renamed to callableMain) in a loop , the application behavior is not consistent as the values of global variables set in previous iteration impact the program flow in the new iteration.

What I would like to do is to reset all the global variables to the default value before the execution of the the new iteration.

for example , the original program is like this

OriginalMain.C

#include <stdio.h>

int global = 3; /* This is the global variable. */

void doSomething(){     
         global++; /* Reference to global variable in a function. */    
}    

     // i want to rename this main method to callableMain() and
     // invoke  it in a loop 
     int main(void){    
       if(global==3) {    
       printf(" All  Is Well \n");    

       doSomething() ;  
     }
     else{

       printf(" Noooo\n");  

       doNothing() ;

     }
     return 0;
}

I want to change this program as follows:

I changed the above file to rename the main() to callableMain()

And my new main methods is as follows:

int main(){  

     for(int i=0;i<20;i++){  

         callableMain();

         // this is where I need to reset the value of global vaiables
        // otherwise the execution flow  changes
     }    
}   

Is this possible to reset all the global variables to the values before main() was invoked ?

The short answer is that there is no magical api call that would reset global variables. The global variables would have to be cached and reused.

like image 850
user193116 Avatar asked Dec 04 '22 11:12

user193116


2 Answers

I would invoke it as a subprocess, modifying its input and output as needed. Let the operating system do the dirty work for you.

The idea is to isolate the legacy program from your new program by relegating it to its own process. Then you have a clean separation between the two. Also, the legacy program is reset to a clean state every time you run it.

First, modify the program so that it reads the input data from a file, and writes its output in a machine-readable format to another file, with the files being given on the command line.

You can then create named pipes (using the mkfifo call) and invoke the legacy program using system, passing it the named pipes on the command line. Then you feed it its input and read back its output.

I am not an expert on these matters; there is probably a better way of doing the IPC. Others here have mentioned fork. However, the basic idea of separating out the legacy code and invoking it as a subprocess is probably the best approach here.

like image 81
David M. Avatar answered May 21 '23 09:05

David M.


fork() early?

You could fork(2) at some early point when you think the globals are in a good state, and then have the child wait on a pipe or something for some work to do. This would require writing any changed state or at least the results back to the parent process but would decouple your worker from your primary control process.

In fact, it might make sense to fork() at least twice, once to set up a worker controller and save the initialized (but not too initialized :-) global state, and then have this worker controller fork() again for each loop you need run.

A simpler variation might be to just modify the code so that the process can start in a "worker mode", and then use fork() or system() to start the application at the top, but with an argument that puts it in to the slave mode.

like image 23
DigitalRoss Avatar answered May 21 '23 09:05

DigitalRoss