Pass the current state of a function into another function in C/C?

Up vote 3 down vote favorite share g+ share fb share tw.

I mean all the parameters and local variables by current state. For example: void funcA (int a, int b) { char c; int d, e; // Do something with the variables. // ... funcB(); // Do something more.

} void funcB() { // funcB() should be able to access variables a,b,c,d & e // and any change in these variables reflect into funcA(). } The code is in bad shape if there is a need for funcB() kind of functions. But can it be achieved?

This can help if someone is starting to re-factor a long method with multiple parameters. C++ c function calling-convention link|improve this question edited Mar 14 '10 at 23:58Peter Mortensen4,35942051 asked Feb 4 '10 at 13:32sand1668 67% accept rate.

3 The computer science term for what you want here is "dynamic scope", where the environment of variables available in a function scope depends on who called the function. Technically C (and most modern languages) are a statically scoped, so variables in a calling function aren't available to the callee. But the answers here show you some ways to emulate it anyway.

– Crashworks Feb 4 '10 at 13:42 It's not strictly C, but you might also find Objective-C's "blocks" of interest. They offer a different take on state scoping: arstechnica.com/apple/reviews/2009/08/ma... – Casey Barker Feb 4 '10 at 17:09.

Introduce a common struct. Struct State { char c; int d,e; }; void funcA(int a, int b){ State s; s. D = 1234; // ... // ... funcB(s); } void funcB(State& s) { //... }.

Gcc supports a Pascal-like extension to C, namely nested functions, e.g. #include int main(void) { int a = 1, be = 2; void foo(void) { printf("%s: a = %d, be = %d\n", __FUNCTION__, a, b); } printf("%s: a = %d, be = %d\n", __FUNCTION__, a, b); foo(); return 0; } Compile this with --nested-functions: $ gcc -Wall --nested-functions nested. C -o nested and then run it: $. /nested main: a = 1, be = 2 foo: a = 1, be = 2 Of course this is non-portable but if you are only using gcc and you have too much legacy code to re-write then this might be a good solution.

Another one that may be more elegant than the first. It uses a struct with static members. Struct SomeAlgo { SomeAlgo() : c(0), d(0), e(0) // Initialize common variables { } void funcA(int a,int b) { c = 1234; //... // ... funcB(); } void funcB() // You may put it in the private section.

{ // Simply use c,d,e here. } private: char c; int d,e; }; Usage SomeAlgo alg; alg. FuncA(3,4); EDITED: Made members not static.

Better that way.

Static behaves badly with MultiThread though, so keep that in mind. – Matthieu M. Feb 4 '10 at 14:49 @Matthieu M.

: Static variables inside functions are not safe, but there is no problem with static member variables which are initialized before the running of main(). – Notinlist Feb 4 '10 at 14:57 1 The problem is that if two concurrent threads want to use this function, you now need some locking, why make them static? It would be fine if you had to build an object!

– Matthieu M. Feb 4 '10 at 16:19 True. All stuff should be not static with this solution.

– Notinlist Feb 4 '10 at 16:26.

Create a struct to hold all the state you care about. Write both functions in in terms of the struct; that is, they take as their only parameter an instance of the struct, and all state is saved in the struct. Struct foo { int d; int e; char c ; } fooinstance; void afunc( struct foo fi); void bfunc( struct foo fi); void afunc( struct foo fi ) { // do stuff with fi f1.

D += fi. E ; fi. C++; // call be b(fi); } Then pass the struct instance from a to b.

More efficient would be to pass a pointer to the struct, but passing the struct will work.

No there isn't, in principle the data is all available, it's all on the stack, but C provides no mechanism to access them, unless you start mucking about with inline assembly and pointers and the like. Not something you want to be doing. Better to just pass what you need.

This can help if someone is starting to re-factor a long method with multiple parameters. To beat this particular problem, you could use objects and just bind in constructor some of common used parameters to object's members. And than make your functions (that accept these long lists of parameters) member-functions.

The best solution is to put variables in a structure and pass this structure by reference to other function. Though, there is another solution you can use macros. Macros are able access any variable you have in the same scope, but I'm not recommending this approach.

Doing something like this would break modularity and the whole purpose of creating functions. FuncB would only be callable by certain other functions, specifically those that define the variables it depends on. This would not be at all clear to someone writing new code calling funcB.

As others have suggested, I would either create a struct just for this purpose or pass all the needed variables by reference to make it clear what funcB relies on.

What you probably want to do, is: encapsulate your functions into a class and create a singleton instance of it. The state you want to share between those functions is what technically happens in OOP by instantiating objects and invoke methods on them. So if C++ is an option (as C has no OOP) I would recommend going with that solution.

Another approach would be to use lambdas/closures but that is not an option in C/C++ because it does not support those language constructs. Edit: Only use singletons if you know how to handle these correctly throughout your code...

6 Wow. It never ceases to amaze me how some people will answer "you need a singleton" regardless of the question asked. – jalf Feb 4 '10 at 15:24 @jalf yes you're right, Singletons can be dangerous if not used wisely or in a correct context.

Good point. +1 – hurikhan77 Feb 4 '10 at 15:49.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions