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.
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
February 2023
January 2023
December 2022
November 2022
October 2022
September 2022
August 2022
November 2021
June 2021
May 2021
April 2021
March 2021
October 2020
September 2020
September 2019
March 2019
June 2018
June 2017
August 2016