Running code outside of main() in C++
While developing plugin system for Map2X reincarnation (more info about that soon), I found a way how to automatically run initialization code without need to call it explicitly in main().
Why?
Sometimes, when you are working on some sort of a plugin system or embedding data into application, you experience a problem, which looks rather simple: How to automatically register all available plugins or data resources?
One of a few common solutions is a special "registering" function, which has to be called in main(), another solution is spoiling main() with dirty REGISTER_PLUGIN() macros, one for each plugin. This approach has one big disadvantage: every time you add new plugin (or data resource), you have to modify also the main(). This is pain-in-the-ass especially when you are developing a library, because every user of your lib must add that code into their main() as well.
How?
The final solution is not as dirty as you might think, but is not pure clean either. There are two totally different ways how to call code before main() and after main(). While calling code before main() is useful for data initialization, code after main() can be used for cleanup of that data.
Talk is cheap, show me the code
One file which does the trick:
/* magic.cpp */ #include <iostream> /* Code executed before main() */ inline int initialize() { std::cout << "Hello!" << std::endl; return 1; } static const int initializer = initialize(); /* Code executed after main() */ class finalize { public: inline finalize() {} inline ~finalize() { std::cout << "Goodbye!" << std::endl; } } finalizer;
One empty main():
/* main.cpp */ int main() { return 0; }
And CMakeLists.txt for compiling with CMake:
# CMakeLists.txt add_executable(magic magic.cpp main.cpp)
When you compile and run this code (cmake . && make in Linux, for example), you will see this:
Hello! Goodbye!
Sadly, this solution doesn't work with static libraries, only with dynamic libraries or when compiled directly into executable.
I found this while digging in Qt resource compiler as an undocumented feature: macros Q_CONSTRUCTOR_FUNCTION() and Q_DESTRUCTOR_FUNCTION() do pretty much the same as the code above. Both macros requires one parameter - name of function (without arguments and returning int).
» Add commentDiscussion: 0 comments
No comments yet.

