Does it analysis the lifecycle of the variable and simply insert the cleanup function call at the right place? Does it have any overhead cost?
I've written two pieces of simple code to compare the performance, and compiled them without optimization.
code1:
#include <stdio.h>
#include <stdlib.h>
void clean_up(int **final_value)
{
free(*final_value);
}
int main(int argc, char **argv)
{
for (int i = 0; i < 10000000; i++) {
int *avar = malloc(sizeof(int));
clean_up(&avar);
}
return 0;
}
code2:
#include <stdio.h>
#include <stdlib.h>
void clean_up(int **final_value)
{
free(*final_value);
}
int main(int argc, char **argv)
{
for (int i = 0; i < 10000000; i++) {
int *avar __attribute__ ((__cleanup__(clean_up))) = malloc(sizeof(int));
}
return 0;
}
And their performance are quite similar.
You'll better compile with some optimization, in particular if you want to look into the generated assembler code (compile with gcc -S -fverbose-asm -O
)
The intuition behind __attribute__((cleanup))
is that GCC is in fact a compiler for all of C, C++, Ada, Fortran, Go.... That attribute is forcing the same internal representation than for C++ destructors of local variables. The cleanup happens at end of current block scope (e.g. at closing brace }
of the block). So the compiler is transforming your code2 with cleanup into the equivalent of code1.
The thing for destructors of global or static variables (which are run after main
has returned) is __attribute__((destructor))
on functions (which are also run at dlclose time for plugins).
So to understand these attributes, you'll better think in C++ terms.
My opinion is that if you need these cleanup
attributes, you should code your thing in C++ not in C. Your code would be much more readable and less compiler dependent. I feel that cleanup
is in practice only useful in generated C code. I never used it (and feel that when I need it, I should switch to C++).