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