Skip to content

Commit

Permalink
lib: bits - macros to simplify expressions when using -Wstrict-bool
Browse files Browse the repository at this point in the history
To be strict-bool compliant, your expressions need to be a bit verbose,
these might simplify things.

There are presently over 400 instances matching HAS_NO_BITS(), and nearly
1300 instances matching HAS_ANY_BITS(), so it's a very common pattern.

Signed-off-by: Phil Carmody <phil@dovecot.fi>
  • Loading branch information
Phil Carmody authored and cmouse committed May 20, 2018
1 parent 861d40b commit 5ea4e2c
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/lib/bits.h
Expand Up @@ -6,6 +6,17 @@

#define BIT(n) (1u << (n))

/* These expressions make it easy to ensure that bit test expressions
are boolean in order to satisfy the in-house -Wstrict-bool. */
/* ((val & bits) == 0) is very common */
#define HAS_NO_BITS(val,bits) (((val) & (bits)) == 0)
/* ((val & bits) != 0) is even more common */
/* Note - illogical behaviour if bits==0, fixing that requires potential
multiple evaluation, but it's a corner case that should never occur. */
#define HAS_ANY_BITS(val,bits) (((val) & (bits)) != 0)
/* ((val & bits) == bits) is uncommon */
#define HAS_ALL_BITS(val,bits) ((~(val) & (bits)) == 0)

/* Returns x, such that x is the smallest power of 2 >= num. */
size_t nearest_power(size_t num) ATTR_CONST;

Expand Down
30 changes: 30 additions & 0 deletions src/lib/test-bits.c
Expand Up @@ -190,6 +190,35 @@ static void test_bits_rotr64(void)
test_end();
}

static void test_bit_tests(void)
{
test_begin("HAS_..._BITS() macro tests");

test_assert(HAS_NO_BITS(1,0));
test_assert(HAS_NO_BITS(2,~2));
test_assert(!HAS_NO_BITS(2,2));

/* OUCH - this vacuously true expression fails. However, if you are
dumb enough to use 0 as bits, then it will also fail in the verbose
case that this macro replaces, it's not a regression. */
/* test_assert(HAS_ANY_BITS(6,0)); */
test_assert(HAS_ANY_BITS(3,1));
test_assert(HAS_ANY_BITS(2,3));
test_assert(!HAS_ANY_BITS(7,~(7|128)));

test_assert(HAS_ALL_BITS(0,0));
test_assert(HAS_ALL_BITS(30,14));
test_assert(!HAS_ALL_BITS(~1,~0));

/* Trap double-evaluation */
unsigned int v=10,b=2;
test_assert(!HAS_NO_BITS(v++, b++) && v==11 && b==3);
test_assert(HAS_ANY_BITS(v++, b++) && v==12 && b==4);
test_assert(HAS_ALL_BITS(v++, b++) && v==13 && b==5);

test_end();
}

void test_bits(void)
{
test_nearest_power();
Expand All @@ -202,4 +231,5 @@ void test_bits(void)
test_bits_rotl64();
test_bits_rotr64();
test_sum_overflows();
test_bit_tests();
}

0 comments on commit 5ea4e2c

Please sign in to comment.