29

In object-oriented languages (C++) you can execute code before main() by using a global object or a class static object and have their constructors run the code you want.

Is there any way to do this in C? I don't have any specific problem I'm trying to solve, I'm just curious. One thing this might be useful for is automatically initializing a library.

Paul Manta
  • 30,618
  • 31
  • 128
  • 208
  • 1
    http://stackoverflow.com/questions/949890/how-can-i-perform-pre-main-initialization-in-c-c-with-avr-gcc – stacker Jan 03 '12 at 14:13
  • @stacker - The question you refer to is specific to Arduino environment. Anyway, answers there may be helpful. – mouviciel Jan 03 '12 at 14:18
  • Not in any standards-compliant way, but you should dig in to what really happens when your operating system loads the binary image and calls the application main function! – Christoffer Jan 03 '12 at 14:29

5 Answers5

31

You can do it with __attribute__ ((constructor)). I've tested the following example with both gcc and clang. That being said, it's not part of the language.

#include <stdio.h>

void __attribute__ ((constructor)) premain()
{
    printf("premain()\n");
}

int main(int argc, char *argv[])
{
    printf("main()\n");
    return 0;
}

It does the following:

$ ./test
premain()
main()

GCC documents it at: https://gcc.gnu.org/onlinedocs/gcc-8.3.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Dan Fego
  • 13,644
  • 6
  • 48
  • 59
12

There are ways using __attribute__ but those are very specific to your compiler and code that is written using these are not really portable. On the other hand, the C language does not provide any start-up modules/libraries.

In C, logically main() is the first function called by the OS. But before calling main(), the OS calls another function called start-up module to setup various environment variables, initialize (un-initialized) static variables, build a stack frame (activation record) and initialize the stack pointer to the start of the stack area and other tasks that have to be done before calling main().

Say if you are writing code for embedded systems where there is no-or-minimal OS to do the above mentioned work, then you should explore these options which are compiler dependent. Other than GCC, Turbo-C and Microsoft C compilers provides facilities to add code in a particular hardware machine (f.e. 8086 machines).

In other words, the start-up modules are not meant for the programmers.

SRG
  • 498
  • 7
  • 19
Sangeeth Saravanaraj
  • 16,027
  • 21
  • 69
  • 98
  • 4
    Wrong, `main` is not the first function called by the OS. Have you heard of [crt0](https://en.wikipedia.org/wiki/Crt0)? `_start` is always called before `main`, and in Windows, `WinMain` is called before `main` also. – MD XF May 16 '17 at 21:34
  • This is False! _start is called by the OS. _start generally (based on your compiler) will call __libc_start_main, which will call main. – Zac Wimer Nov 03 '18 at 06:01
6

With gcc, you can do so by using the constructor function attribute, e.g.

__attribute__ ((__constructor__)) 
void foo(void) {
        ...
}

This will invoke foo before main.

Note: This is probably not portable to other compilers.

Zulan
  • 21,896
  • 6
  • 49
  • 109
0

If your compiler can compile cpp files you can add a file with a class that call in the costructor your initialization code. The class must be allocated statically. For example:

#include "ext.h"

class cext
{
public:
   cext()
   {
      ExtInit();
   }

   ~cext(){};
};

cext g_cext;

The ExtInit() function must be defined as extern "C" in file ext.h.

#ifdef __cplusplus
extern "C" {
#endif
void   ExtInit   (void);
#ifdef __cplusplus
}
#endif

bttcld
  • 67
  • 7
  • 3
    And this drags in the entire C++ runtime library, and ties anyone who want to use the code to that one specific C++ runtime. There's a reason why the question was tagged C and not C++. – Andrew Henle Feb 02 '22 at 17:11
  • It’s still potentially useful so I’m glad it’s here, I might use this. Also can’t you do this without the standard library? Or is the runtime library a different thing? I know of libgcc but that’s used for C too – Heath Mitchell Feb 21 '23 at 18:36
-1

You can initialize global variables but not call functions within these initializations.

mouviciel
  • 66,855
  • 13
  • 106
  • 140