nostrdb

an unfairly fast embedded nostr database backed by lmdb
git clone git://jb55.com/nostrdb
Log | Files | Refs | Submodules | README | LICENSE

compiler.h (8363B)


      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 #if HAVE_UNALIGNED_ACCESS
      7 #define alignment_ok(p, n) 1
      8 #else
      9 #define alignment_ok(p, n) ((size_t)(p) % (n) == 0)
     10 #endif
     11 
     12 #ifndef COLD
     13 #if HAVE_ATTRIBUTE_COLD
     14 /**
     15  * COLD - a function is unlikely to be called.
     16  *
     17  * Used to mark an unlikely code path and optimize appropriately.
     18  * It is usually used on logging or error routines.
     19  *
     20  * Example:
     21  * static void COLD moan(const char *reason)
     22  * {
     23  *    fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno));
     24  * }
     25  */
     26 #define COLD __attribute__((__cold__))
     27 #else
     28 #define COLD
     29 #endif
     30 #endif
     31 
     32 #ifndef NORETURN
     33 #if HAVE_ATTRIBUTE_NORETURN
     34 /**
     35  * NORETURN - a function does not return
     36  *
     37  * Used to mark a function which exits; useful for suppressing warnings.
     38  *
     39  * Example:
     40  * static void NORETURN fail(const char *reason)
     41  * {
     42  *    fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno));
     43  *    exit(1);
     44  * }
     45  */
     46 #define NORETURN __attribute__((__noreturn__))
     47 #else
     48 #define NORETURN
     49 #endif
     50 #endif
     51 
     52 #ifndef PRINTF_FMT
     53 #if HAVE_ATTRIBUTE_PRINTF
     54 /**
     55  * PRINTF_FMT - a function takes printf-style arguments
     56  * @nfmt: the 1-based number of the function's format argument.
     57  * @narg: the 1-based number of the function's first variable argument.
     58  *
     59  * This allows the compiler to check your parameters as it does for printf().
     60  *
     61  * Example:
     62  * void PRINTF_FMT(2,3) my_printf(const char *prefix, const char *fmt, ...);
     63  */
     64 #define PRINTF_FMT(nfmt, narg) \
     65     __attribute__((format(__printf__, nfmt, narg)))
     66 #else
     67 #define PRINTF_FMT(nfmt, narg)
     68 #endif
     69 #endif
     70 
     71 #ifndef CONST_FUNCTION
     72 #if HAVE_ATTRIBUTE_CONST
     73 /**
     74  * CONST_FUNCTION - a function's return depends only on its argument
     75  *
     76  * This allows the compiler to assume that the function will return the exact
     77  * same value for the exact same arguments.  This implies that the function
     78  * must not use global variables, or dereference pointer arguments.
     79  */
     80 #define CONST_FUNCTION __attribute__((__const__))
     81 #else
     82 #define CONST_FUNCTION
     83 #endif
     84 
     85 #ifndef PURE_FUNCTION
     86 #if HAVE_ATTRIBUTE_PURE
     87 /**
     88  * PURE_FUNCTION - a function is pure
     89  *
     90  * A pure function is one that has no side effects other than it's return value
     91  * and uses no inputs other than it's arguments and global variables.
     92  */
     93 #define PURE_FUNCTION __attribute__((__pure__))
     94 #else
     95 #define PURE_FUNCTION
     96 #endif
     97 #endif
     98 #endif
     99 
    100 #if HAVE_ATTRIBUTE_UNUSED
    101 #ifndef UNNEEDED
    102 /**
    103  * UNNEEDED - a variable/function may not be needed
    104  *
    105  * This suppresses warnings about unused variables or functions, but tells
    106  * the compiler that if it is unused it need not emit it into the source code.
    107  *
    108  * Example:
    109  * // With some preprocessor options, this is unnecessary.
    110  * static UNNEEDED int counter;
    111  *
    112  * // With some preprocessor options, this is unnecessary.
    113  * static UNNEEDED void add_to_counter(int add)
    114  * {
    115  *    counter += add;
    116  * }
    117  */
    118 #define UNNEEDED __attribute__((__unused__))
    119 #endif
    120 
    121 #ifndef NEEDED
    122 #if HAVE_ATTRIBUTE_USED
    123 /**
    124  * NEEDED - a variable/function is needed
    125  *
    126  * This suppresses warnings about unused variables or functions, but tells
    127  * the compiler that it must exist even if it (seems) unused.
    128  *
    129  * Example:
    130  *    // Even if this is unused, these are vital for debugging.
    131  *    static NEEDED int counter;
    132  *    static NEEDED void dump_counter(void)
    133  *    {
    134  *        printf("Counter is %i\n", counter);
    135  *    }
    136  */
    137 #define NEEDED __attribute__((__used__))
    138 #else
    139 /* Before used, unused functions and vars were always emitted. */
    140 #define NEEDED __attribute__((__unused__))
    141 #endif
    142 #endif
    143 
    144 #ifndef UNUSED
    145 /**
    146  * UNUSED - a parameter is unused
    147  *
    148  * Some compilers (eg. gcc with -W or -Wunused) warn about unused
    149  * function parameters.  This suppresses such warnings and indicates
    150  * to the reader that it's deliberate.
    151  *
    152  * Example:
    153  *    // This is used as a callback, so needs to have this prototype.
    154  *    static int some_callback(void *unused UNUSED)
    155  *    {
    156  *        return 0;
    157  *    }
    158  */
    159 #define UNUSED __attribute__((__unused__))
    160 #endif
    161 #else
    162 #ifndef UNNEEDED
    163 #define UNNEEDED
    164 #endif
    165 #ifndef NEEDED
    166 #define NEEDED
    167 #endif
    168 #ifndef UNUSED
    169 #define UNUSED
    170 #endif
    171 #endif
    172 
    173 #ifndef IS_COMPILE_CONSTANT
    174 #if HAVE_BUILTIN_CONSTANT_P
    175 /**
    176  * IS_COMPILE_CONSTANT - does the compiler know the value of this expression?
    177  * @expr: the expression to evaluate
    178  *
    179  * When an expression manipulation is complicated, it is usually better to
    180  * implement it in a function.  However, if the expression being manipulated is
    181  * known at compile time, it is better to have the compiler see the entire
    182  * expression so it can simply substitute the result.
    183  *
    184  * This can be done using the IS_COMPILE_CONSTANT() macro.
    185  *
    186  * Example:
    187  *    enum greek { ALPHA, BETA, GAMMA, DELTA, EPSILON };
    188  *
    189  *    // Out-of-line version.
    190  *    const char *greek_name(enum greek greek);
    191  *
    192  *    // Inline version.
    193  *    static inline const char *_greek_name(enum greek greek)
    194  *    {
    195  *        switch (greek) {
    196  *        case ALPHA: return "alpha";
    197  *        case BETA: return "beta";
    198  *        case GAMMA: return "gamma";
    199  *        case DELTA: return "delta";
    200  *        case EPSILON: return "epsilon";
    201  *        default: return "**INVALID**";
    202  *        }
    203  *    }
    204  *
    205  *    // Use inline if compiler knows answer.  Otherwise call function
    206  *    // to avoid copies of the same code everywhere.
    207  *    #define greek_name(g)                        \
    208  *         (IS_COMPILE_CONSTANT(greek) ? _greek_name(g) : greek_name(g))
    209  */
    210 #define IS_COMPILE_CONSTANT(expr) __builtin_constant_p(expr)
    211 #else
    212 /* If we don't know, assume it's not. */
    213 #define IS_COMPILE_CONSTANT(expr) 0
    214 #endif
    215 #endif
    216 
    217 #ifndef WARN_UNUSED_RESULT
    218 #if HAVE_WARN_UNUSED_RESULT
    219 /**
    220  * WARN_UNUSED_RESULT - warn if a function return value is unused.
    221  *
    222  * Used to mark a function where it is extremely unlikely that the caller
    223  * can ignore the result, eg realloc().
    224  *
    225  * Example:
    226  * // buf param may be freed by this; need return value!
    227  * static char *WARN_UNUSED_RESULT enlarge(char *buf, unsigned *size)
    228  * {
    229  *    return realloc(buf, (*size) *= 2);
    230  * }
    231  */
    232 #define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
    233 #else
    234 #define WARN_UNUSED_RESULT
    235 #endif
    236 #endif
    237 
    238 
    239 #if HAVE_ATTRIBUTE_DEPRECATED
    240 /**
    241  * WARN_DEPRECATED - warn that a function/type/variable is deprecated when used.
    242  *
    243  * Used to mark a function, type or variable should not be used.
    244  *
    245  * Example:
    246  * WARN_DEPRECATED char *oldfunc(char *buf);
    247  */
    248 #define WARN_DEPRECATED __attribute__((__deprecated__))
    249 #else
    250 #define WARN_DEPRECATED
    251 #endif
    252 
    253 
    254 #if HAVE_ATTRIBUTE_NONNULL
    255 /**
    256  * NO_NULL_ARGS - specify that no arguments to this function can be NULL.
    257  *
    258  * The compiler will warn if any pointer args are NULL.
    259  *
    260  * Example:
    261  * NO_NULL_ARGS char *my_copy(char *buf);
    262  */
    263 #define NO_NULL_ARGS __attribute__((__nonnull__))
    264 
    265 /**
    266  * NON_NULL_ARGS - specify that some arguments to this function can't be NULL.
    267  * @...: 1-based argument numbers for which args can't be NULL.
    268  *
    269  * The compiler will warn if any of the specified pointer args are NULL.
    270  *
    271  * Example:
    272  * char *my_copy2(char *buf, char *maybenull) NON_NULL_ARGS(1);
    273  */
    274 #define NON_NULL_ARGS(...) __attribute__((__nonnull__(__VA_ARGS__)))
    275 #else
    276 #define NO_NULL_ARGS
    277 #define NON_NULL_ARGS(...)
    278 #endif
    279 
    280 #if HAVE_ATTRIBUTE_RETURNS_NONNULL
    281 /**
    282  * RETURNS_NONNULL - specify that this function cannot return NULL.
    283  *
    284  * Mainly an optimization opportunity, but can also suppress warnings.
    285  *
    286  * Example:
    287  * RETURNS_NONNULL char *my_copy(char *buf);
    288  */
    289 #define RETURNS_NONNULL __attribute__((__returns_nonnull__))
    290 #else
    291 #define RETURNS_NONNULL
    292 #endif
    293 
    294 #if HAVE_ATTRIBUTE_SENTINEL
    295 /**
    296  * LAST_ARG_NULL - specify the last argument of a variadic function must be NULL.
    297  *
    298  * The compiler will warn if the last argument isn't NULL.
    299  *
    300  * Example:
    301  * char *join_string(char *buf, ...) LAST_ARG_NULL;
    302  */
    303 #define LAST_ARG_NULL __attribute__((__sentinel__))
    304 #else
    305 #define LAST_ARG_NULL
    306 #endif
    307 
    308 #if HAVE_BUILTIN_CPU_SUPPORTS
    309 /**
    310  * cpu_supports - test if current CPU supports the named feature.
    311  *
    312  * This takes a literal string, and currently only works on glibc platforms.
    313  *
    314  * Example:
    315  * if (cpu_supports("mmx"))
    316  *    printf("MMX support engaged!\n");
    317  */
    318 #define cpu_supports(x) __builtin_cpu_supports(x)
    319 #else
    320 #define cpu_supports(x) 0
    321 #endif /* HAVE_BUILTIN_CPU_SUPPORTS */
    322 
    323 #endif /* CCAN_COMPILER_H */