Showing posts with label gcc. Show all posts
Showing posts with label gcc. Show all posts

Friday, 23 November 2012

Using the gcc cleanup attribute

Section 6.36 of the GCC manual describes the rather interesting cleanup variable attribute.   This allows one to specify a function to call when the variable goes out of scope.

The caveat is that the cleanup attribute can only be used with auto function scope variables, so it cannot be used on function parameters or static variables.

So what about an simple example?  How about automatic free'ing on variables that go out of scope?  This way we can be lazy and do automatic garbage collecting without having to remember to free() each allocation. Now, I'm not recommending this is good practice, I am just using this as an example.

Below I define a macro autofree that we use on the auto variables that we want to garbage collect on.   When the variable goes out of scope __autofree() is called and it is passing the address of the variable.  GCC insists on the helper function to be passed as a pointer to the type of the variable being cleaned. To handle any particular type I used a void * argument __autofree() and then I cast this to a void ** to allow me to free the memory that the variable pointed to, so a little bit of legitimate slight of hand being used here.

 #include <stdlib.h>  
 #include <stdio.h>  
   
 #define autofree __attribute((cleanup(__autofree)))  
   
 void __autofree(void *p)  
 {  
     void **_p = (void**)p;  
   
     printf("free -> %p\n", *_p);  
     free(*_p);  
 }  
   
 void *myalloc(size_t sz)  
 {  
     void *ptr;  
   
     if ((ptr = malloc(sz)) == NULL) {  
         fprintf(stderr, "malloc failed.\n");  
         exit(1);  
     }  
     printf("malloc -> %p\n", ptr);  
   
     return ptr;  
 }  
   
 int main(int argc, char **argv)  
 {  
     autofree char *x = myalloc(32);  
   
     {  
         autofree int *y = myalloc(64);  
   
         printf("y = %p\n", y);  
     }  
     printf("x = %p\n", x);  
   
     return 0;
 }  

In this example, I malloc memory for x and then y.  Then y and then x go out of scope and the cleaner function __autofree() frees the memory in that order:

 malloc -> 0x1504010  
 malloc -> 0x1504040  
 y = 0x1504040  
 free -> 0x1504040  
 x = 0x1504010  
 free -> 0x1504010  

I'm sure there are other ways that this can be creatively used (or abused...); as it stands it is a GCC extension so it is not portable C in any shape or form.

Tuesday, 16 February 2010

GCC inline assembler explained

There are times when the Linux Kernel uses inline assembler to either use specific instruction sequences for optimal code efficiency or to use processor features that are not accessible in C (e.g. memory barriers, I/O instructions, manipulating processor state, etc..).

GCC provides a mechanism to enable one to place inlined assembler into C source but to the beginner the syntax can be a little impenetrable. A useful little primer and guide to GCC inline assembler can be found at http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

The primer is a little old, but nevertheless it is still valid and very useful.

Monday, 15 June 2009

GCC built in #defines

The following rune dumps out the #define values in GCC:

gcc -E -dM -xc /dev/null

Quite handy sometimes!