Constructors and Destructors are special functions. These are one of the features provided by an Object Oriented Programming language. Constructors and Destructors are defined inside an object class. When an object is instantiated, ie. defined of or dynamically allocated of that class type, the Constructor function of that class is executed automatically. There might be many constructors of which the correct implementation is automatically selected by the compiler. When this object is destroyed or deallocated, the Destructor function is automatically executed. For example when the scope of the object has finished or the object was dynamically allocated and now being freed. The Constructors and the Destructors are generally contains initialization and cleanup codes respectively required by an object to operate correctly. Because these functions are automatically invoked by the compiler therefore the programmer freed from the headache of calling them manually.

There is no such thing called ‘constructors’ and ‘destructors’ in C programming language or in structured languages, although there is no boundaries on defining such functions which act like them. You need to make functions which act like the constructors and destructors and then call them manually.

The GCC constructor and destructor attributes

GCC has attributes with which you can tell the compiler about how a lot of things should be handled by the compiler. Among such attributes the below function attributes are used to define constructors and destructors in C language. These would only work under GCC. As there is no objects and class approach in C the working of these functions are not like C++ or other OOP language constructor and destructors. With this feature, the functions defined as constructor function would be executed before the function main starts to execute, and the destructor would be executed after the main has finished execution. The GCC function attributes to define constructors and destructors are as follows:

__attribute__((constructor))
__attribute__((destructor))
__attribute__((constructor (PRIORITY)))
__attribute__((destructor (PRIORITY)))

For example, to declare a function named begin () as a constructor, and end () as a destructor, you need to tell gcc about these functions through the following declaration.

void begin (void) __attribute__((constructor));
void end (void) __attribute__((destructor));

An alternate way to flag a function as a C constructor or destructor can also be done at the time of the function definition.

__attribute__((constructor)) void begin (void)
{
 /* Function Body */
}
__attribute__((destructor)) void end (void)
{
 /* Function Body */
}

After declaring the functions as constructors and destructors as above, gcc will automatically call begin () before calling main () and call end () after leaving main or after the execution of exit () function. The following sample code demonstrates the feature.

#include <stdio.h>

void begin (void) __attribute__((constructor));
void end (void) __attribute__((destructor));

int main (void)
{
  printf ("\nInside main ()");
}

void begin (void)
{
  printf ("\nIn begin ()");
}

void end (void)
{
  printf ("\nIn end ()\n");
}

Execution of this code will come up with an output which clearly shows how the functions were executed.


In begin ()
Inside main ()
In end ()

Multiple Constructors and Destructors

Multiple constructors and destructors can be defined and can be automatically executed depending upon their priority. In this case the syntax is __attribute__((constructor (PRIORITY))) and __attribute__((destructor (PRIORITY))). In this case the function prototypes would look like.

void begin_0 (void) __attribute__((constructor (101)));
void end_0 (void) __attribute__((destructor (101)));

void begin_1 (void) __attribute__((constructor (102)));
void end_1 (void) __attribute__((destructor (102)));

void begin_2 (void) __attribute__((constructor (103)));
void end_2 (void) __attribute__((destructor (103)));

The constructors with lower priority value would be executed first. The destructors with higher priority value would be executed first. So the constructors would be called in the sequence: begin_0, begin_1 (), begin_2 () . and the destructors are called in the sequence end_2 (), end_1 (), end_0 (). Note the LIFO execution sequence of the constructors and destructors depending on the priority values.

The sample code below demonstrates this

#include <stdio.h>

void begin_0 (void) __attribute__((constructor (101)));
void end_0 (void) __attribute__((destructor (101)));

void begin_1 (void) __attribute__((constructor (102)));
void end_1 (void) __attribute__((destructor (102)));

void begin_2 (void) __attribute__((constructor (103)));
void end_2 (void) __attribute__((destructor (103)));

int main (void)
{
  printf ("\nInside main ()");
}

void begin_0 (void)
{
  printf ("\nIn begin_0 ()");
}

void end_0 (void)
{
  printf ("\nIn end_0 ()");
}

void begin_1 (void)
{
  printf ("\nIn begin_1 ()");
}

void end_1 (void)
{
  printf ("\nIn end_1 ()");
}

void begin_2 (void)
{
  printf ("\nIn begin_2 ()");
}

void end_2 (void)
{
  printf ("\nIn end_2 ()");
}

The output is as below:


In begin_0 ()
In begin_1 ()
In begin_2 ()
Inside main ()
In end_2 ()
In end_1 ()
In end_0 ()

Note that, when compiling with priority values between 0 and 100 (inclusive), gcc would throw you warnings that the priority values from 0 to 100 are reserved for implementation, so these values might be used internally that we might not know. So it is better to use values out of this range. The value of the priority does not depend, instead the relative values of the priority is the determinant of the sequence of execution.

Note that the function main () is not the first function/code block to execute in your code there are a lot of code already executed before main starts to execute. The function main is the user’s code entry point, but the program entry point is not the main function. There is a startup function which prepares the environment for the execution. The startup functions first call the functions declared as constructors and then calls the main. When main returns the control to the startup function it then calls those functions which you have declared as the destructors. There are separate sections in the executable .ctors and .dtors which hold these functions. (not discussed here).

As there is no class object creation in C language does not have such features like in C++ or other OOP languages but this feature can bring some flexibility by calling the functions automatically on execution and termination of the code which you needed to do inside the main. For example one use may be like, you have a dynamically allocated global variable, might point to a linked list head or an array, or a file descriptor which you can allocate inside a constructor. If some error is encountered you can immediately call exit () or the program terminates normally, depending on the error code you can make cleanup in the destructors.

Another good use is probably calling the initialization functions of some library, a bunch of which needs to be called in each program. You can make a separate file with the constructor files calling properly the library functions (probably operating on globals) and calling the library cleanup functions in the destructors. Whenever you make a program what you need to do is to compile your code with this file containing the constructors and destructors and forget about calling the initialization and cleanup functions in the main program. But doing this will make your code unportable, as it would only work under GCC.

References and Links

Advertisements

31 thoughts on “C Language Constructors and Destructors with GCC

  1. This is a nice tip to those who want the “power” of constructors and deconstructors in the C language. It adds a lot of implicit functionality to your program, but my question is: Why would you add this ‘hacking’ – I see it as a bunch of hacks – to your program when you could also use a fully developed OOP language such as C++, which does natively support constructors and deconstructors?

    1. Definitely, this is not the exact definition of what we call the constructor and the destructor. Depends if one would want to design the problem with a function oriented approach or object oriented approach. I am familiar with a functional oriented approach, and a lot of times you would need to call a chunk of functions in each program using some library which might be done in some way in the constructors. Or code a generic error handling routine in the destructor, which you need not bother to call, just link it and the compiler would do it automatically. This feature would only introduce some automated calls of functions which would otherwise need manual calls that is all it does. But if a certain problem has been designed with OOD method then it would be easier to implement with an OOP language, and should be done.
      This post was to make people aware of the existence of this feature. Unfortunately I could not provide you with any real example where this feature is used.
      Thanks for stopping by.

    1. The bad exam schedules bar me from working on new articles, and also finalize the drafts. I hope i would be able to post very soon. You might like to take an email subscription to get notified whenever i post. Thanks for visiting and the support.

  2. constructor and destructor attributed functions also work in libraries (static or shared) and dll’s.
    This allows regular ‘C’ interface libraries to “auto initialize” so you don’t have to call library_I_really_need_init(); and library_I_really_needed_deinit().
    If you link a lib, static or shared, it can initialize/deinitialize itself if it’s authors avail themselves of the con/destructor attributes.
    There are lots of benefits when appying this facility to dll’s. Again, the dll can self initialize. Which means the loading process doesn’t need to dlsym a known symbol… which removes a constraint on the dll author and allows them to provide a functional block as a .a, .so, or .dll without any special code (no #iddef’s to avoid known symbol collision if you choose to link 2 libraries statically instead of loading their dll incarnations).
    For dll’s the constructor is called befor dlopen() returns, and the destructor runs before dlclose() returns or when the application exits.
    If you can’t think of a cool application for this, you’re just not trying hard enough.

    (C has advantages over C++, not so much in the expresiveness or more pervasive con/destructor support but in the ABI compatibility issues (HUGE), useability from a C source base (C++ libs are difficult for C apps or libs to lerverage), required resources (additional libs), and code size (many C++ features bloat code if one isn’t VERY careful).

    1. I have mentioned the idea of auto initialization of libraries, but i could not find an actual application, because of my limited exposure to codes. I will give this a deeper look. Thanks for the comment.

    1. That is not possible in C Language. As i have wrote “As there is no objects and class approach in C the working of these functions are not like C++ or other OOP language constructor and destructors. ” This is something like a constructor and destructor, but not exactly as defined in OOP paradigm.

  3. I’m using this in my program and also the nice functions preinit, init, fini and atexit.
    This is particularly nice if you make self contained code like daemonizer.c that do not need any other introduction in the program.
    The text about destructors being run when exit() is called, seems to be malfunctioning at the moment. I do not know if this has to do with kernel versions (2.6.32 & 3.6.8) or something else. To run code when exit() is called you do need to add atexit-functions.

    1. I tested the code calling exit (), the function assigned as a destructor was properly called. I am running gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2) on Linux-3.6.6-1.fc16.x86_64 . Great to know about the atexit function, it was right there under stdlib, but never noticed it in the man pages. Couldn’t get the preinit, init, and fini functions in C Standard library, Is it part of any C library ?

      1. gcc (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2)
        Linux 3.6.8-2.fc17.x86_64 #1 SMP Tue Nov 27 19:35:02 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

  4. Nice article!
    I’ve run into problems with destructors though:
    Actual tests using constructors and destructors is working nice until you try exit().
    According to documentation destructors should be run, but this is not the case.
    My libc is 4.7.2
    At the moment I add atexit-functions to solve it.

    1. I wrote a code which catches the SIGINT and within the signal handler, simply calls exit (0), it works using the gcc destructor construct, the end function is called. It also works when i register end with atexit. BUT if i do not register the signal handler, that is, signal (SIGINT, SIG_DFL) , then the end function is NOT called.

      I think i should give a pass through the link you shared. It is worth a look. Possibly you would also like to have a look at stackoverflow.com and drop a question there?

  5. I tried with constructor(priority) and I am getting compilation error. Can you tell me where I went wrong. below is the code.

    #include <stdio.h>
    void beforeMain() __attribute__((constructor));
    void beforeMain1() __attribute__((constructor(101)));
    void beforeMain2() __attribute__((constructor(102)));
    
    void beforeMain1()
    {
            printf("before main 1\n");
    }
    void beforeMain2()
    {
            printf("before main 2\n");
    }
    void beforeMain()
    {
            printf("before main \n");
    }
    int main()
    {
            printf("In main function \n");
    }
    

    Thanks in advance
    http://chanduthedev.blogspot.in/

    1. I can’t see any problem with your code, runs perfectly at my end. Which compiler are using? Note that this is a strictly gcc feature, as mentioned in the post, and is not a part of C Language.

      Thanks for visiting!

      1. Thanks for quick reply.
        My system is MacBook pro and gcc version is
        i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)

        and I am getting below compilation error.

        beforeMain.c:3: error: wrong number of arguments specified for ‘constructor’ attribute
        beforeMain.c:4: error: wrong number of arguments specified for ‘constructor’ attribute

        Thanks in advance,
        http://chanduthedev.blogspot.in/

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s