aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYaroslav de la Peña Smirnov <yps@yaroslavps.com>2024-04-15 22:44:46 +0300
committerYaroslav de la Peña Smirnov <yps@yaroslavps.com>2024-04-15 22:44:46 +0300
commitac22f535bcd14f8e201d410265aab268899d7753 (patch)
tree24bb27d966394012dec1c5c86aa3d96283f998a8
parent026588af6ac371bb06bef844d7fb021feb926eab (diff)
downloadc-wares-ac22f535bcd14f8e201d410265aab268899d7753.tar.gz
c-wares-ac22f535bcd14f8e201d410265aab268899d7753.zip
utils.h: update ARRAY_SIZEHEADmaster
Update ARRAY_SIZE macro so that we can use it in more places, including where comma expressions aren't allowed.
-rw-r--r--utils.h28
1 files changed, 22 insertions, 6 deletions
diff --git a/utils.h b/utils.h
index cb7d795..66430ab 100644
--- a/utils.h
+++ b/utils.h
@@ -15,6 +15,17 @@
#define static_assert(exp, msg) _Static_assert(exp, msg)
#endif
+/**
+ * BUILD_BUG_ON_ZERO - throws compilation error if true, expressions returns 0.
+ * @cond: condition
+ *
+ * Force a compilation error if condition is true, but also produce a
+ * result (of value 0 and type int), so the expression can be used
+ * e.g. in a structure initializer (or where-ever else comma expressions
+ * aren't permitted).
+ */
+#define BUILD_BUG_ON_ZERO(cond) ((int)(sizeof(struct { int : (-!!(cond)); })))
+
#define same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
#define container_of(ptr, T, member) \
@@ -25,11 +36,16 @@
(T *)((void *)(ptr)-offsetof(T, member)); \
})
-#define ARRAY_SIZE(arr) \
- ({ \
- static_assert(!same_type((arr), &(arr)[0]), \
- "variable is not an array"); \
- sizeof(arr) / sizeof(*arr); \
- })
+/**
+ * __ASSERT_IS_ARRAY - throw a compilation error if @arr is not an array.
+ * @arr: variable to check.
+ */
+#define __ASSERT_IS_ARRAY(arr) BUILD_BUG_ON_ZERO(same_type((arr), &(arr)[0]))
+
+/**
+ * ARRAY_SIZE - return the number of elements in @arr.
+ * @arr: array of any type.
+ */
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(*arr) + __ASSERT_IS_ARRAY(arr))
#endif