I'd like to do some stuffs before main
function. I have multiple source files. In each file, there is some work that needs to be done before main
. It was no problem in C++, but problematic with C.
In C++, this can be done by two ways:
For example, static const int __register_dummy_ = __AddRegisterMetaInfo(...);
However, in C, either ways is impossible. Obviously, there is no constructor. So, the first option is inherently impossible.
I thought that the second option would be possible, but not compiled in C (I tested only with Visual C++. It gives C2099.). C only allows a constant to a non-automatic variable.
Is there any way to call some functions before main?
EDIT: It seems that many people just got misunderstand what I really wanted to do. Sorry for writing this question in a simplified way.
What I needed to do is implementing a sort of C++ runtime class information feature, just like MFC's approach. In this approach, I need to get some information from all source code. For example, say each source file has a definition of a class, and I'd like to see all information (e.g., class names and the parent class). The easiest way is placing a static constructor in each file, and each constructor accesses a global data structure and register its information. But, I also wanted to find a way to implement a similar thing in C. So, simply calling a pre_main_job
in main
can't be an answer to me.
Note that this abuse of static constructor also can be found in LLVM compiler suite. Each optimization/analysis feature is implemented as a pass. All these passes are registered via a static constructor.
For a number of compiler specific solutions you can take a look at the fips_premain.c file from the OpenSSL distribution (you can view it online in a bunch of places, here for instance).
The MSVC specific part looks something like (FINGERPRINT_premain
being the function to be executed before main
):
# ifdef _WINDLL
__declspec(dllexport) /* this is essentially cosmetics... */
# endif
void FINGERPRINT_premain(void);
static int premain_wrapper(void) { FINGERPRINT_premain(); return 0; }
# ifdef _WIN64
# pragma section(".CRT$XCU",read)
__declspec(allocate(".CRT$XCU"))
# else
# pragma data_seg(".CRT$XCU")
# endif
static int (*p)(void) = premain_wrapper;
/* This results in pointer to premain to appear in .CRT segment,
* which is traversed by Visual C run-time initialization code.
* This applies to both Win32 and [all flavors of] Win64. */
# pragma data_seg()