These articles are written by Codalogic empowerees as a way of sharing knowledge with the programming community. They do not necessarily reflect the opinions of Codalogic.

GCC's __attribute__((constructor))

By: Pete, October 2022

While digging through the workings of QEMU I discovered GCC's __attribute__((constructor)) and __attribute__((destructor)). These tell GCC to run the associated function either before entering main() or after exiting main().

They work in both C and C++ so I have written the example below in a C dialect.

Hopefully the comments in the example explain what is happening well enough.

#include <stdio.h>

// Assigning functions to be executed before and
// after main()

// This function is specified to execute before
// main() using __attribute__((constructor))
void __attribute__((constructor)) before_main()
{
    printf( "%s called before main()\n", __PRETTY_FUNCTION__);
}

// Functions can also be specified to execute before or after
// main() in their prototype
void __attribute__((destructor)) after_main();

// Here is main()!
int main()
{
    printf( "I am in %s\n", __PRETTY_FUNCTION__);
}

// This function was specified to execute after main()
// using __attribute__((destructor)) in its earlier prototype
void after_main()
{
    printf( "%s called after main()\n", __PRETTY_FUNCTION__);
}

// If a prototype specifies __attribute__((constructor)) or
// __attribute__((destructor)) it is optional whether the
// definition also specifies the attribute
void __attribute__((destructor)) another_after_main();
void __attribute__((destructor)) another_after_main()
{
    printf( "%s called after main()\n", __PRETTY_FUNCTION__);
}

// BOth attributes can be specified on the same function
void __attribute__((constructor)) __attribute__((destructor))
another_before_and_after_main()
{
    printf( "%s called before and after main()\n", __PRETTY_FUNCTION__);
}

// It's possible to specify __attribute__((constructor)) in the
// prototype and __attribute__((destructor)) in the definition
// (or vice versa)
void __attribute__((constructor)) before_and_after_main();
void __attribute__((destructor)) before_and_after_main()
{
    printf( "%s called before and after main()\n", __PRETTY_FUNCTION__);
}

Here is the output:

void before_main() called before main()
void another_before_and_after_main() called before and after main()
void before_and_after_main() called before and after main()
I am in int main()
void before_and_after_main() called before and after main()
void another_before_and_after_main() called before and after main()
void another_after_main() called after main()
void after_main() called after main()

You can play with the example at: https://godbolt.org/z/cxvTnsz17