prevent using functions before initialization, constructors-like in C
This is the way I get to prevent funA,funB,funC, etc.. for being used before init
#define INIT_KEY 0xC0DE //any number except 0, is ok
sta开发者_开发技巧tic int initialized=0;
int Init()
{
//many init task
initialized=INIT_KEY;
}
int funA()
{
if (initialized!=INIT_KEY) return 1;
//..
}
int funB()
{
if (initialized!=INIT_KEY) return 1;
//..
}
int funC()
{
if (initialized!=INIT_KEY) return 1;
//..
}
The problem with this approach is that if some of those function is called within a loop so "if (initialized!=INIT_KEY)" is called again, and again, although it's not necessary.
It's a good example of why constructors are useful haha, If it were an object I would be sure that when it was created, initialization was called, but in C, I don't know how to do it.
Any other ideas are welcome!
Use pointer to function.
At construct time, point the functions at the function that does the required initialization, then updates the function pointers to point to the actual functions that do the work.
I have done this with arrays of pointer to member functions in a class. The class has an internal integer which says what state the object it in. The integer is used to subscript into the array of pointer to member functions... State 0 does the init. State 1, does the work, State 2 sets things back to state 1.
It worked very cleanly.
You could use some kind of assertions utilizing some preprocessor macros:
#ifdef DEBUG
# define ENSURE_INITIALIZED(obj) \
do { \
if (obj->initialized != INIT_CODE) { \
fprintf (stderr, "Object %p not initliaized (%s:%d)\n", obj, __FILE__, __LINE__); \
abort (); \
} \
} while (0)
#else
# define ENSURE_INITIALIZED(obj)
#endif
voif foo (Object *obj) {
ENSURE_INITIALIZED (obj);
}
This will check for initialization code but only in debug builds - in production builds it will evaluate to no-op.
Calling abort
will abnormally terminate program, typically leaving a core dump, or interrupting program when run in debugger.
Put your functions inside a structure (use function pointers to access them). Provide a "construct" function to create that structure and assign the correct function addresses in the structure. Almost the same idea as EvilTeach.
You can think about different solutions. In the loop, no matter the chosen solution, some extra code will be always executed (at best behind the scenes) to prevent the functions to be executed. You could skip in the loop the execution of funX, but it would be extra code to check if funX can be executed, placed differently.
Since commonly initialization is done before other task, this is a strange problem, or a misnaming (you should not call it initialization).
If you want, the functions can call the initializer by themselves, like
if (!initialized) initialize();
Always extra code, and the !initialized will be always false from then on.
But the way to avoid to check again and again is to call explicitly the initialization in the correct place, before the game begins to play for real. (Otherwise don't call it initialization).
If it were an object, ... you don't need object for this. To "trig" a constructor, you must create the object (at least, in many OO languages) with, say, new MyClass()
or "declaring it"; here the call to "new" (that is not a call, but for this speech we can think this way) or the "declaration" is changed into a call to an explicit initializer. Your apparently simple
Object a;
// ...
a.method(); //or
Object *a = new Object();
// ...
a->method();
would be
init()
// ...
funA();
Even if this example does not "match" your "need", it should make clear that an explicit initializer is not so tremendously bad and OO languages really are not necessary to "fix" this problem.
You can control when you can call those funcs, so you don't need checking at all; it happens in many libraries that require first a call to special init function before you can use them, or "odd" behaviours must be expected.
A solution would be to do the initialization like this (in each file):
static int initResult = Init();
When program will start, those static variables will be initialized automatically and the function will be called.
IMPORTANT NOTE: The order of the initialization is undefined if you need to do such initializations in more than one file (usually the linking order of the objects dictates the order of the initialization - but there is no rule for that). So you must be careful when doing this.
精彩评论