c++ - Is it good practice to hide Initialization code "before main"? -
i building c++ library , need initialize opengl context program ( , other default resource objects ). practice ( considering modern c++ semantics ) "hide init. code" in code chunk being called before main ? cannot use static variables because need initialize things in specific order ! (i cannot init texture before openglm or sdl !)
here code :
#include <stdio.h> #ifdef _msc_ver // msvc / msvc++ 2015 #define ccall __cdecl #pragma section(".crt$xcu",read) #define initializer(f) \ static void __cdecl f(void); \ __declspec(allocate(".crt$xcu")) void (__cdecl*f##_)(void) = f; \ static void __cdecl f(void) #elif defined(__gnuc__) gcc / g++ #define ccall #define initializer(f) \ static void f(void) __attribute__((constructor)); \ static void f(void) #endif static void ccall finalize(void) { /* king of delete / dispose here : sdl_quit, ... */ } initializer(initialize) { /* here startup code ... */ }
the standard, section 3.6.2, says non-local static variables may be initialized before first statement of main
:
it implementation-defined whether dynamic initialization of non-local variable static storage duration done before first statement of main.
thus, doesn't must be initialized before first statement of main
. there no way in c++ enforce constraint initialized before main()
called, except static variables defined in same compilation unit main.
the best solution include resource management within main
itself:
int main() { // load resources (housekeeping code) // real work (applicative code) // release resources (housekeeping code) }
if want separate applicative code housekeeping code, commonly used approach use inversion of control (sometimes via template method pattern):
- a separate function or method dedicated applicative or user code
- the function
main
responsible both doing housekeeping , invoking user-code or applicative-code function or method.
this exemplified below:
// function below expected exist framework // must implemented user int usermain() { // implement user-code here } // code below implemented framework // expects user have implemented function usermain int main() { frameworkdata theframeworkdata; // framework performs initialization house-keeping here theframeworkdata.initialize(); // framework invokes user-code (inversion of control) usermain(); // framework performs clean-up house-keeping here theframeworkdata.cleanup(); }
Comments
Post a Comment