简体   繁体   中英

Most correct way for bit checking in C

I reading a book "Linux Kernel. Development. Third Edition." by Robert Love.

And in softirq section it's comment next piece of code:

    u32 pending;
    pending = local_softirq_pending();

    if (pending) {
            struct softirq_action *h;
            /* reset the pending bitmask */
            set_softirq_pending(0);
            h = softirq_vec;
            do {
                    if (pending & 1) /* STEP 4 */
                            h->action(h);
                    h++;
                    pending >>= 1;
            } while (pending);
    }

He discribe step by step what happens and most unclear step for me is 4:

  1. If the first bit in pending is set, h->action(h) is called

I have following code to check if bit set like in book:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define BIT_SET(n) ((1) << (n))
#define BIT_CLEAR(n) ~((1) << (n))

int main(void)
{
        unsigned char bits = 0x0;

        bits |= BIT_SET(1);

        if (bits & (1 << 1))
                printf("TEST CHECK SET 1\n");

        if (bits & 1)
                printf("TEST CHECK SET 2\n");

        bits &= BIT_CLEAR(1);

        if (!(bits >> 1) & 1UL)
                printf("BITS UNSET\n");

        return 0;
}

compiled with:

gcc main.c -O0 -Wall -Wextra -Werror. 

I always check if bit set with this one:

if (bits & (1 << n)) 

And my code make output like this:

TEST CHECK SET 1
BITS UNSET

Why if (bits & 1) statment is not work?:

So from several option which should I use and what exactly last one check?

if (bit & (1 << n))

if ((bit >> n) & 1)

if (bit & n) 

I always check if bit set with this one: if (bits & (1 << n))

This checks n -th bit in place; the code from the book, however, shifts the bit into the least-significant-bit position prior to making the check with bits & 1 . In other words, by the time the code reaches the if (bits & 1) the value of bits has already been shifted such that the bit of interest is in 1-s position.

This is similar to your other check

if ((bit >> n) & 1)

except (bit >> n) part is done by performing bit >>= 1 operation n times in a loop.

Note that in order for this code to work correctly bit must be unsigned.

So from several option which should I use and what exactly last one check?

You misinterpreted the last check: it's not checking bit n , it's checking bit against the entire bit pattern of n 's binary representation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM