Tag
Hash :
a0d14d15
Author :
Date :
2011-07-06T16:47:25
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
#ifndef CCAN_COMPILER_H
#define CCAN_COMPILER_H
#include "config.h"
#ifndef COLD
#if HAVE_ATTRIBUTE_COLD
/**
* COLD - a function is unlikely to be called.
*
* Used to mark an unlikely code path and optimize appropriately.
* It is usually used on logging or error routines.
*
* Example:
* static void COLD moan(const char *reason)
* {
* fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno));
* }
*/
#define COLD __attribute__((cold))
#else
#define COLD
#endif
#endif
#ifndef NORETURN
#if HAVE_ATTRIBUTE_NORETURN
/**
* NORETURN - a function does not return
*
* Used to mark a function which exits; useful for suppressing warnings.
*
* Example:
* static void NORETURN fail(const char *reason)
* {
* fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno));
* exit(1);
* }
*/
#define NORETURN __attribute__((noreturn))
#else
#define NORETURN
#endif
#endif
#ifndef PRINTF_FMT
#if HAVE_ATTRIBUTE_PRINTF
/**
* PRINTF_FMT - a function takes printf-style arguments
* @nfmt: the 1-based number of the function's format argument.
* @narg: the 1-based number of the function's first variable argument.
*
* This allows the compiler to check your parameters as it does for printf().
*
* Example:
* void PRINTF_FMT(2,3) my_printf(const char *prefix, const char *fmt, ...);
*/
#define PRINTF_FMT(nfmt, narg) \
__attribute__((format(__printf__, nfmt, narg)))
#else
#define PRINTF_FMT(nfmt, narg)
#endif
#endif
#ifndef IDEMPOTENT
#if HAVE_ATTRIBUTE_CONST
/**
* IDEMPOTENT - a function's return depends only on its argument
*
* This allows the compiler to assume that the function will return the exact
* same value for the exact same arguments. This implies that the function
* must not use global variables, or dereference pointer arguments.
*/
#define IDEMPOTENT __attribute__((const))
#else
#define IDEMPOTENT
#endif
#endif
#if HAVE_ATTRIBUTE_UNUSED
#ifndef UNNEEDED
/**
* UNNEEDED - a variable/function may not be needed
*
* This suppresses warnings about unused variables or functions, but tells
* the compiler that if it is unused it need not emit it into the source code.
*
* Example:
* // With some preprocessor options, this is unnecessary.
* static UNNEEDED int counter;
*
* // With some preprocessor options, this is unnecessary.
* static UNNEEDED void add_to_counter(int add)
* {
* counter += add;
* }
*/
#define UNNEEDED __attribute__((unused))
#endif
#ifndef NEEDED
#if HAVE_ATTRIBUTE_USED
/**
* NEEDED - a variable/function is needed
*
* This suppresses warnings about unused variables or functions, but tells
* the compiler that it must exist even if it (seems) unused.
*
* Example:
* // Even if this is unused, these are vital for debugging.
* static NEEDED int counter;
* static NEEDED void dump_counter(void)
* {
* printf("Counter is %i\n", counter);
* }
*/
#define NEEDED __attribute__((used))
#else
/* Before used, unused functions and vars were always emitted. */
#define NEEDED __attribute__((unused))
#endif
#endif
#ifndef UNUSED
/**
* UNUSED - a parameter is unused
*
* Some compilers (eg. gcc with -W or -Wunused) warn about unused
* function parameters. This suppresses such warnings and indicates
* to the reader that it's deliberate.
*
* Example:
* // This is used as a callback, so needs to have this prototype.
* static int some_callback(void *unused UNUSED)
* {
* return 0;
* }
*/
#define UNUSED __attribute__((unused))
#endif
#else
#ifndef UNNEEDED
#define UNNEEDED
#endif
#ifndef NEEDED
#define NEEDED
#endif
#ifndef UNUSED
#define UNUSED
#endif
#endif
#ifndef IS_COMPILE_CONSTANT
#if HAVE_BUILTIN_CONSTANT_P
/**
* IS_COMPILE_CONSTANT - does the compiler know the value of this expression?
* @expr: the expression to evaluate
*
* When an expression manipulation is complicated, it is usually better to
* implement it in a function. However, if the expression being manipulated is
* known at compile time, it is better to have the compiler see the entire
* expression so it can simply substitute the result.
*
* This can be done using the IS_COMPILE_CONSTANT() macro.
*
* Example:
* enum greek { ALPHA, BETA, GAMMA, DELTA, EPSILON };
*
* // Out-of-line version.
* const char *greek_name(enum greek greek);
*
* // Inline version.
* static inline const char *_greek_name(enum greek greek)
* {
* switch (greek) {
* case ALPHA: return "alpha";
* case BETA: return "beta";
* case GAMMA: return "gamma";
* case DELTA: return "delta";
* case EPSILON: return "epsilon";
* default: return "**INVALID**";
* }
* }
*
* // Use inline if compiler knows answer. Otherwise call function
* // to avoid copies of the same code everywhere.
* #define greek_name(g) \
* (IS_COMPILE_CONSTANT(greek) ? _greek_name(g) : greek_name(g))
*/
#define IS_COMPILE_CONSTANT(expr) __builtin_constant_p(expr)
#else
/* If we don't know, assume it's not. */
#define IS_COMPILE_CONSTANT(expr) 0
#endif
#endif
#ifndef WARN_UNUSED_RESULT
#if HAVE_WARN_UNUSED_RESULT
/**
* WARN_UNUSED_RESULT - warn if a function return value is unused.
*
* Used to mark a function where it is extremely unlikely that the caller
* can ignore the result, eg realloc().
*
* Example:
* // buf param may be freed by this; need return value!
* static char *WARN_UNUSED_RESULT enlarge(char *buf, unsigned *size)
* {
* return realloc(buf, (*size) *= 2);
* }
*/
#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define WARN_UNUSED_RESULT
#endif
#endif
#endif /* CCAN_COMPILER_H */