X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Fcompiler%2Fcompiler.h;h=caa89edc5968a6b5cbcb800876d6ae66672e2720;hp=be229670fd127a5f89e9e9bc6b14e4a7cc48ddce;hb=97026cedabce510b2e2e547120f04fe0f6a5ecab;hpb=c4c5fed020ba44b9930119672a36a1cb33aff090 diff --git a/ccan/compiler/compiler.h b/ccan/compiler/compiler.h index be229670..caa89edc 100644 --- a/ccan/compiler/compiler.h +++ b/ccan/compiler/compiler.h @@ -1,103 +1,170 @@ +/* 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_ATTRIBUTE - a function is unlikely to be called. + * 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: - * void COLD_ATTRIBUTE moan(const char *reason) - * { - * fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno)); - * } + * static void COLD moan(const char *reason) + * { + * fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno)); + * } */ -#define COLD_ATTRIBUTE __attribute__((cold)) +#define COLD __attribute__((__cold__)) #else -#define COLD_ATTRIBUTE +#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_ATTRIBUTE - 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. + * 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_ATTRIBUTE(2,3) my_printf(char *prefix, char *format, ...); + * void PRINTF_FMT(2,3) my_printf(const char *prefix, const char *fmt, ...); */ -#define PRINTF_ATTRIBUTE(nfmt, narg) \ +#define PRINTF_FMT(nfmt, narg) \ __attribute__((format(__printf__, nfmt, narg))) #else -#define PRINTF_ATTRIBUTE(nfmt, narg) +#define PRINTF_FMT(nfmt, narg) +#endif #endif +#ifndef CONST_FUNCTION #if HAVE_ATTRIBUTE_CONST /** - * IDEMPOTENT_ATTRIBUTE - a function's return depends only on its argument + * 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 IDEMPOTENT_ATTRIBUTE __attribute__((const)) +#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 IDEMPOTENT_ATTRIBUTE +#define PURE_FUNCTION +#endif +#endif #endif #if HAVE_ATTRIBUTE_UNUSED +#ifndef UNNEEDED /** - * UNNEEDED_ATTRIBUTE - a parameter/variable/function may not be needed + * UNNEEDED - a variable/function may not be needed * - * This suppresses warnings about unused variables or parameters, but tells + * 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 config options, this is unnecessary. - * static UNNEEDED_ATTRIBUTE int counter; - * ... - * #ifdef DEBUG - * counter++; - * #endif - * ... - * // With some config options, this is unnecessary. - * static UNNEEDED_ATTRIBUTE int add_to_counter(int add) - * { - * counter += add; - * } + * // 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 __attribute__((unused)) +#define UNNEEDED __attribute__((__unused__)) +#endif +#ifndef NEEDED #if HAVE_ATTRIBUTE_USED /** - * NEEDED_ATTRIBUTE - a parameter/variable/function is needed + * NEEDED - a variable/function is needed * - * This suppresses warnings about unused variables or parameters, but tells + * 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 UNNEEDED_ATTRIBUTE int counter; - * static UNNEEDED_ATTRIBUTE void dump_counter(void) + * static NEEDED int counter; + * static NEEDED void dump_counter(void) * { * printf("Counter is %i\n", counter); * } */ -#define NEEDED_ATTRIBUTE __attribute__((used)) +#define NEEDED __attribute__((__used__)) #else /* Before used, unused functions and vars were always emitted. */ -#define NEEDED_ATTRIBUTE __attribute__((unused)) +#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 -#define UNNEEDED_ATTRIBUTE -#define NEEDED_ATTRIBUTE +#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? @@ -117,7 +184,7 @@ * const char *greek_name(enum greek greek); * * // Inline version. - * static inline _greek_name(enum greek greek) + * static inline const char *_greek_name(enum greek greek) * { * switch (greek) { * case ALPHA: return "alpha"; @@ -139,4 +206,84 @@ /* 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, 2); + */ +#define NON_NULL_ARGS(index, ...) __attribute__((__nonnull__(index, __VA_ARGS__))) +#else +#define NO_NULL_ARGS +#define NON_NULL_ARGS(index, ...) +#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 + #endif /* CCAN_COMPILER_H */