cstatic-variables

Calling some functions before main in C


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:

  1. Exploiting a constructor of a global class/struct.
  2. Calling a function to a global variable

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.


Solution

  • 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()