commit f184ebe57ae8798cdc9e0d8f7df935c708c14e53
parent 0d2db13f14f9a0e8fceed3633e8e38673557b4f3
Author: Robert Russell <robertrussell.72001@gmail.com>
Date: Sun, 12 Mar 2023 17:47:45 -0700
Add STATIC macro and improve (un)likely macros
We can now write
if likely(cond) {...}
instead of
if (likely(cond)) {...}
(and similarly for unlikely) which hints that (un)likely is not part
of the condition.
Diffstat:
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/inc/def.h b/inc/def.h
@@ -21,8 +21,8 @@
#ifdef __GNUC__
#define NOINLINE __attribute__((noinline))
#define UNUSED __attribute__((unused))
-#define likely(x) __builtin_expect((x), 1)
-#define unlikely(x) __builtin_expect((x), 0)
+#define likely(x) (__builtin_expect((x), 1))
+#define unlikely(x) (__builtin_expect((x), 0))
#else
#define NOINLINE
#define UNUSED
@@ -30,6 +30,22 @@
#define unlikely(x) (x)
#endif
+/* STATIC is a macro for creating static literals. Usage:
+ * STATIC(int, 3)
+ * STATIC(char[], "abc")
+ * STATIC(struct {int a; int b;}, {1, 2})
+ * The result of each of these expressions is a pointer to static data, which
+ * in particular mean it can be passed to functions that retain pointers after
+ * the caller returns. In the last use case, the value argument contains a
+ * comma outside of parentheses, which is why we use varargs in the
+ * implementation. The type argument must never contain a comma outside of
+ * parentheses. */
+#if __STDC_VERSION__ >= 202300L
+#define STATIC(T, ...) (&(static T){__VA_ARGS__})
+#elif defined(__GNUC__)
+#define STATIC(T, ...) ({static __typeof__(T) tmp = __VA_ARGS__; &tmp;})
+#endif
+
#if CHAR_BIT != 8
#error "Expected CHAR_BIT == 8"
#endif