From: Zbigniew Jędrzejewski-Szmek Date: Sat, 11 Apr 2026 11:06:56 +0000 (+0200) Subject: fundamental: add ABS_DIFF macro X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=efbd8a26d65c68a16c64e3d8cb5ae9d298ac6abb;p=thirdparty%2Fsystemd.git fundamental: add ABS_DIFF macro Sometimes we want need to diff two unsigned numbers, which is awkward because we need to cast them to something with a sign first, if we want to use abs(). Let's add a helper that avoids the function call altogether. Also drop unnecessary parens arounds args which are delimited by commas. --- diff --git a/src/fundamental/macro-fundamental.h b/src/fundamental/macro-fundamental.h index a5300d591ae..6ed6cf2f8a0 100644 --- a/src/fundamental/macro-fundamental.h +++ b/src/fundamental/macro-fundamental.h @@ -171,7 +171,7 @@ #define U64_GB (UINT64_C(1024) * U64_MB) #undef MAX -#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b)) +#define MAX(a, b) __MAX(UNIQ, a, UNIQ, b) #define __MAX(aq, a, bq, b) \ ({ \ const typeof(a) UNIQ_T(A, aq) = (a); \ @@ -234,7 +234,7 @@ assert_cc(sizeof(long long) == sizeof(intmax_t)); }) #undef MIN -#define MIN(a, b) __MIN(UNIQ, (a), UNIQ, (b)) +#define MIN(a, b) __MIN(UNIQ, a, UNIQ, b) #define __MIN(aq, a, bq, b) \ ({ \ const typeof(a) UNIQ_T(A, aq) = (a); \ @@ -242,6 +242,14 @@ assert_cc(sizeof(long long) == sizeof(intmax_t)); UNIQ_T(A, aq) < UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \ }) +#define ABS_DIFF(a, b) __ABS_DIFF(UNIQ, a, UNIQ, b) +#define __ABS_DIFF(aq, a, bq, b) \ + ({ \ + const typeof(a) UNIQ_T(A, aq) = (a); \ + const typeof(b) UNIQ_T(B, bq) = (b); \ + UNIQ_T(A, aq) < UNIQ_T(B, bq) ? UNIQ_T(B, bq) - UNIQ_T(A, aq) : UNIQ_T(A, aq) - UNIQ_T(B, bq); \ + }) + /* evaluates to (void) if _A or _B are not constant or of different types */ #define CONST_MIN(_A, _B) \ (__builtin_choose_expr( \ @@ -312,7 +320,7 @@ assert_cc(sizeof(long long) == sizeof(intmax_t)); }) #undef CLAMP -#define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high)) +#define CLAMP(x, low, high) __CLAMP(UNIQ, x, UNIQ, low, UNIQ, high) #define __CLAMP(xq, x, lowq, low, highq, high) \ ({ \ const typeof(x) UNIQ_T(X, xq) = (x); \ @@ -329,7 +337,7 @@ assert_cc(sizeof(long long) == sizeof(intmax_t)); * computation should be possible in the given type. Therefore, we use * [x / y + !!(x % y)]. Note that on "Real CPUs" a division returns both the * quotient and the remainder, so both should be equally fast. */ -#define DIV_ROUND_UP(x, y) __DIV_ROUND_UP(UNIQ, (x), UNIQ, (y)) +#define DIV_ROUND_UP(x, y) __DIV_ROUND_UP(UNIQ, x, UNIQ, y) #define __DIV_ROUND_UP(xq, x, yq, y) \ ({ \ const typeof(x) UNIQ_T(X, xq) = (x); \ @@ -341,11 +349,11 @@ assert_cc(sizeof(long long) == sizeof(intmax_t)); #define __ROUND_UP(q, x, y) \ ({ \ const typeof(y) UNIQ_T(A, q) = (y); \ - const typeof(x) UNIQ_T(B, q) = DIV_ROUND_UP((x), UNIQ_T(A, q)); \ + const typeof(x) UNIQ_T(B, q) = DIV_ROUND_UP(x, UNIQ_T(A, q)); \ typeof(x) UNIQ_T(C, q); \ MUL_SAFE(&UNIQ_T(C, q), UNIQ_T(B, q), UNIQ_T(A, q)) ? UNIQ_T(C, q) : (typeof(x)) -1; \ }) -#define ROUND_UP(x, y) __ROUND_UP(UNIQ, (x), (y)) +#define ROUND_UP(x, y) __ROUND_UP(UNIQ, x, y) #define CASE_F_1(X) case X: #define CASE_F_2(X, ...) case X: CASE_F_1( __VA_ARGS__) diff --git a/src/test/test-macro.c b/src/test/test-macro.c index 7f7bf1ce8db..9a9a1fa2dac 100644 --- a/src/test/test-macro.c +++ b/src/test/test-macro.c @@ -130,6 +130,13 @@ TEST(MAX) { assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10); } +TEST(ABS_DIFF) { + ASSERT_EQ(ABS_DIFF(5, 3), 2); + ASSERT_EQ(ABS_DIFF(3, 5), 2); + ASSERT_EQ(ABS_DIFF(5llu, 2llu), 3llu); + ASSERT_EQ(ABS_DIFF(3llu, 5llu), 2llu); +} + #pragma GCC diagnostic push #ifdef __clang__ # pragma GCC diagnostic ignored "-Waddress-of-packed-member"