All[*] constructors for file-scope objects get called before reaching main, as do all initializer expressions for non-object file-scope variables.
Edit: Also, all[*] destructors for all file-scope objects get called in reverse order of construction after main exits. You could, theoretically, put your fibonacci program in an object's destructor.
[*] Note that 'all' ignores the behavior of dynamically loading and unloading libraries that your program wasn't directly linked with. Those technically are outside the base C++ language, though.
It is most likely implemented as (or a variant of it):
void print_fibs()
{
//implementation
}
int ignore = (print_fibs(), 0);
int main() {}
In this code, the global variable ignore has to be initialized before entering into main() function. Now in order to initialize the global, print_fibs() needs to be executed where you can do anything — in this case, compute fibonacci numbers and print them! A similar thing I've shown in the following question (which I had asked long back):
Note that such code is not safe and should be best avoided in general. For example, the std::cout object may not be initialized when print_fibs() is executed, if so then what would std::cout do in the function? However, if in other circumstances, it doesn't depend on such initialization order, then it is safe to call initialization functions (which is a common practice in C and C++).
I know some examples like that you tell. One way to get it is using the template metaprogramming. Using it you can move some compute process to the compilation.
Here you can get an example with the Fibonacci numbers
If you use it in a static class constructor and you can write the numbers without need to write any code in the main function.