Never been to TextSnippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

« Newer Snippets
Older Snippets »
5 total  XML / RSS feed 

Multiple __attributes__

Multiple __attributes__ can be strung together on a single declaration, and this is not uncommon in practice. You can either use two separate __attribute__s, or use one with a comma-separated list:

/* send printf-like message to stderr and exit */
extern void die(const char *format, ...)
        __attribute__((noreturn))
        __attribute__((format(printf, 1, 2)));

/*or*/

extern void die(const char *format, ...)
        __attribute__((noreturn, format(printf, 1, 2)));

__attribute__ const

This attribute marks the function as considering only its numeric parameters. This is mainly intended for the compiler to optimize away repeated calls to a function that the compiler knows will return the same value repeatedly. It applies mostly to math functions that have no static state or side effects, and whose return is solely determined by the inputs.

In this highly-contrived example, the compiler normally must call the square() function in every loop even though we know that it's going to return the same value each time:

extern int square(int n) __attribute__((const));

...
        for (i = 0; i < 100; i++ )
        {
                total += square(5) + i;
        }


By adding __attribute__((const)), the compiler can choose to call the function just once and cache the return value.

__attribute__ noreturn

This attribute tells the compiler that the function won't ever return, and this can be used to suppress errors about code paths not being reached. The C library functions abort() and exit() are both declared with this attribute:

extern void exit(int) __attribute__((noreturn));
extern void abort(void) __attribute__((noreturn));

$ cat test2.c
extern void exitnow() __attribute__((noreturn));

int foo(int n)
{
        if ( n > 0 )
                exitnow();
        else
                return 0;
}

$ cc -c -Wall test2.c
no warnings!

__attribute__ format

This __attribute__ allows assigning printf-like or scanf-like characteristics to the declared function, and this enables the compiler to check the format string against the parameters provided throughout the code. This is exceptionally helpful in tracking down hard-to-find bugs.

There are two flavors:

* __attribute__((format(printf,m,n)))
* __attribute__((format(scanf,m,n)))

but in practice we use the first one much more often.

The (m) is the number of the "format string" parameter, and (n) is the number of the first variadic parameter.


/* like printf() but to standard error only */
extern void eprintf(const char *format, ...)
        __attribute__((format(printf, 1, 2)));  /* 1=format 2=params */

/* printf only if debugging is at the desired level */
extern void dprintf(int dlevel, const char *format, ...)
        __attribute__((format(printf, 2, 3)));  /* 2=format 3=params */

$ cat test.c
1  extern void eprintf(const char *format, ...)
2               __attribute__((format(printf, 1, 2)));
3
4  void foo()
5  {
6      eprintf("s=%s\n", 5);             /* error on this line */
7
8      eprintf("n=%d,%d,%d\n", 1, 2);    /* error on this line */
9  }

$ cc -Wall -c test.c
test.c: In function `foo':
test.c:6: warning: format argument is not a pointer (arg 2)
test.c:8: warning: too few arguments for format

Set the default compiler on Mac OS X Tiger

Some stuff won't compile with the shiny new gcc 4.0 on Tiger.
To use gcc 3.3 :
sudo gcc_select 3.3


To revert to gcc 4.0 :
sudo gcc_select 4.0


(found on the forum, thanks Damelon!)
« Newer Snippets
Older Snippets »
5 total  XML / RSS feed