vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

compiler.h

(5958B)


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