summaryrefslogtreecommitdiffstats
path: root/ccan/ccan/compiler/compiler.h
blob: 562b29ec71cc13969ab0d111477608cdbc9d9c36 (plain)
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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
/* CC0 (Public domain) - see LICENSE file for details */
#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 CONST_FUNCTION
#if HAVE_ATTRIBUTE_CONST
/**
 * CONST_FUNCTION - 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 CONST_FUNCTION __attribute__((__const__))
#else
#define CONST_FUNCTION
#endif

#ifndef PURE_FUNCTION
#if HAVE_ATTRIBUTE_PURE
/**
 * PURE_FUNCTION - a function is pure
 *
 * A pure function is one that has no side effects other than it's return value
 * and uses no inputs other than it's arguments and global variables.
 */
#define PURE_FUNCTION __attribute__((__pure__))
#else
#define PURE_FUNCTION
#endif
#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


#if HAVE_ATTRIBUTE_DEPRECATED
/**
 * WARN_DEPRECATED - warn that a function/type/variable is deprecated when used.
 *
 * Used to mark a function, type or variable should not be used.
 *
 * Example:
 * WARN_DEPRECATED char *oldfunc(char *buf);
 */
#define WARN_DEPRECATED __attribute__((__deprecated__))
#else
#define WARN_DEPRECATED
#endif


#if HAVE_ATTRIBUTE_NONNULL
/**
 * NO_NULL_ARGS - specify that no arguments to this function can be NULL.
 *
 * The compiler will warn if any pointer args are NULL.
 *
 * Example:
 * NO_NULL_ARGS char *my_copy(char *buf);
 */
#define NO_NULL_ARGS __attribute__((__nonnull__))

/**
 * NON_NULL_ARGS - specify that some arguments to this function can't be NULL.
 * @...: 1-based argument numbers for which args can't be NULL.
 *
 * The compiler will warn if any of the specified pointer args are NULL.
 *
 * Example:
 * char *my_copy2(char *buf, char *maybenull) NON_NULL_ARGS(1);
 */
#define NON_NULL_ARGS(...) __attribute__((__nonnull__(__VA_ARGS__)))
#else
#define NO_NULL_ARGS
#define NON_NULL_ARGS(...)
#endif

#if HAVE_ATTRIBUTE_RETURNS_NONNULL
/**
 * RETURNS_NONNULL - specify that this function cannot return NULL.
 *
 * Mainly an optimization opportunity, but can also suppress warnings.
 *
 * Example:
 * RETURNS_NONNULL char *my_copy(char *buf);
 */
#define RETURNS_NONNULL __attribute__((__returns_nonnull__))
#else
#define RETURNS_NONNULL
#endif

#if HAVE_ATTRIBUTE_SENTINEL
/**
 * LAST_ARG_NULL - specify the last argument of a variadic function must be NULL.
 *
 * The compiler will warn if the last argument isn't NULL.
 *
 * Example:
 * char *join_string(char *buf, ...) LAST_ARG_NULL;
 */
#define LAST_ARG_NULL __attribute__((__sentinel__))
#else
#define LAST_ARG_NULL
#endif

#if HAVE_BUILTIN_CPU_SUPPORTS
/**
 * cpu_supports - test if current CPU supports the named feature.
 *
 * This takes a literal string, and currently only works on glibc platforms.
 *
 * Example:
 * if (cpu_supports("mmx"))
 *	printf("MMX support engaged!\n");
 */
#define cpu_supports(x) __builtin_cpu_supports(x)
#else
#define cpu_supports(x) 0
#endif /* HAVE_BUILTIN_CPU_SUPPORTS */

#endif /* CCAN_COMPILER_H */