Bit Fields in C. What are they, and how do I use them?

แชร์
ฝัง
  • เผยแพร่เมื่อ 26 ก.ย. 2024
  • Patreon ➤ / jacobsorber
    Courses ➤ jacobsorber.th...
    Website ➤ www.jacobsorbe...
    ---
    Bit Fields in C. What are they, and how do I use them? // Bit fields are a common programming tool that a lot of beginners don't know about. This video explains how they work, and shows you how to use them in three different scenarios, to pass options into functions, to make reduced-size integers, and to treat integers as arrays of bits.
    ***
    Welcome! I post videos that help you learn to program and become a more confident software developer. I cover beginner-to-advanced systems topics ranging from network programming, threads, processes, operating systems, embedded systems and others. My goal is to help you get under-the-hood and better understand how computers work and how you can use them to become stronger students and more capable professional developers.
    About me: I'm a computer scientist, electrical engineer, researcher, and teacher. I specialize in embedded systems, mobile computing, sensor networks, and the Internet of Things. I teach systems and networking courses at Clemson University, where I also lead the PERSIST research lab.
    More about me and what I do:
    www.jacobsorbe...
    people.cs.clem...
    persist.cs.clem...
    To Support the Channel:
    + like, subscribe, spread the word
    + contribute via Patreon --- [ / jacobsorber ]
    + rep the channel with nerdy merch --- [teespring.com/...]
    Source code is also available to Patreon supporters. --- [jsorber-youtub...]

ความคิดเห็น • 97

  • @shmuel-k
    @shmuel-k 3 ปีที่แล้ว +21

    I've been coding for 6 years and I've used bitfields before (as an API consumer, not as an implementer) but didn't know how they worked. Now I feel I understand. Thanks for providing this clear and concise intro to them!

    • @JacobSorber
      @JacobSorber  3 ปีที่แล้ว +5

      Glad I could help!

  • @AceAufWand
    @AceAufWand 4 ปีที่แล้ว +56

    Great videos. I'd like to add a little something from my own experience with struct bit-field.
    Be careful with struct bit-field, it looks like a good idea when dealing with hardware registers or exchange protocol which are most of the time (all the time ?) in form of an CPU word whose each bit as a special meaning.
    But compiler padding, endianness and register access could make things very non-intuitive. I hit this wall the hard way, loosing days to figure out why my serial link was not working ^^.
    The best way to understand how a processor handles bit-field is to check its ABI (one of the least known and most important document about processor in my opinion).
    Additionnal: the packed attribute tends to remove compiler memory aligment assumption that could transform a simple word access into several one byte access, hence saving 2 bytes from memory could cost you some CPU cycle, that might or might not be a problem, the trade-off is up to you.

    • @edwinontiveros8701
      @edwinontiveros8701 4 ปีที่แล้ว +6

      Just use *pahole* to make sure the packing of structs is adequate and optimal, this may also reduce cache misses and memory mis-alignment. Compilers are not very smart at optimizing structure packing and padding therefore using the aforementioned static analysis tool, can potentially save hundreds of MG or even GB's of memory and thus potentiallyCPU cycles if you rearrange the members properly, on the long run of course.
      As for endianess, unless working with very proprietary or esoteric hardware (or tool chain even) byte endianess shouldn't be an issue anymore, most (if not all) low-level server side modules already have addressed this by standardizing and implementing abstractions to detect and convert between modes back and forth, unless the network protocol is being made from scratch, instead of using an already proven one (which you should only do for educational purposes anyway) then running into endianess hell is almost 100% guaranteed, specially if other devices on the network aren't aware of each other and their endianess-coping mechanisms differ considerably.
      In simpler words:
      It would be like expecting an English speaker understand a Mandarin speaker just because they can send a stream of vibrations to each other, without them getting prior knowledge of the other peer's language lexical structure, although they might get some 'sounds' right and the other will understand them, most of them will not be grammatically and syntactically correct, which is what byte endianess is to a processor, and will not be understood correctly or at all.
      Greetings and very good advice for those beginning to lurk on the depths of networking protocols and low level implementation.

  • @nafisahmed6247
    @nafisahmed6247 9 หลายเดือนก่อน +2

    I work in embedded and I regularly use bit fields for structs, however SET_BIT & CLR_BIT macros were completely new to me. Thanks man!

    • @raccoon1160
      @raccoon1160 9 หลายเดือนก่อน

      If you do use these macros, make sure to wrap the variables inside the macro definition with parentheses: e.g. `#define SET_BIT(BF, N) (BF) |= (0x0001ULL

    • @TurboXray
      @TurboXray หลายเดือนก่อน

      Wow! You definitely should not. Embedded world is where this can trip you up the most. Since it's not defined behavior/layout under the hood.

    • @nafisahmed6247
      @nafisahmed6247 19 วันที่ผ่านมา

      @@TurboXray it depends on the compiler, for the mcu compiler that i am using it is documented to be supported.

  • @NordicFrog
    @NordicFrog 4 ปีที่แล้ว +9

    Thank you for putting these videos out here on youtube. I have learned so much from your videos.
    You manage to put so much information in such a short video, and still have it be very clear and concise.

  • @malusmundus-9605
    @malusmundus-9605 2 ปีที่แล้ว +1

    DUDE THIS IS SIIIIIICCCCCKKKKK... I'm going to use this all the time now. This will really clean up my function parameters.

  • @papasmurf9146
    @papasmurf9146 2 ปีที่แล้ว +10

    With struct of bit-fields, one thing to watch for is that the layout of the bits is compiler / CPU architecture dependent: sometimes the first bit is the high bit and sometimes the low bit:
    #include
    #include
    union {
    uint32_t value;
    struct {
    uint32_t a:2;
    uint32_t b:2;
    uint32_t c:2;
    uint32_t d:2;
    };
    } var;
    int main(int argc, char* argv[])
    {
    var.value = 0;
    var.a = 3;
    printf("%08x
    ", var.value);
    }
    On my Linux/Intel system, this will print out 00000003. However, on other systems it could print out c0000000 (and since I don't have handy access to one, I wasn't able to double check; Solaris on Sparc comes to mind as a probable different bit-packer.)

    • @TurboXray
      @TurboXray หลายเดือนก่อน +1

      I've sadly experienced this issue when trying to port a code base.

  • @inferno3853
    @inferno3853 ปีที่แล้ว +2

    Good Video, one small optimization at 11:57 would be doing (BF & (1

    • @charankoppineni4498
      @charankoppineni4498 ปีที่แล้ว

      what?

    • @inferno3853
      @inferno3853 ปีที่แล้ว

      ​@@charankoppineni4498 for (BF >> N) & 1, BF >> N can not be known at compile time in this usecase since BF might be anything, so it has to do this calculation at runtime.
      doing BF & (1

    • @charankoppineni4498
      @charankoppineni4498 ปีที่แล้ว

      @@inferno3853 but the value of N keeps changing as the loop get iterates right ? Even then, it is known to the compiler?

    • @inferno3853
      @inferno3853 ปีที่แล้ว

      @@charankoppineni4498 in this case, its up to the compiler to decide what to do. it could inline the entire thing and just leave out the loop entirely (which would just make it look like a series of checks instead of a loop in the machine code).
      but yeah in general you're right, N could be variable as well, it is just not as likely as BF being one though.
      you should note though that this optimization is very useless today since we have fast computers nowadays and i just wanted to comment it to make people understand small optimizations like this more

  • @pseudopseudo3679
    @pseudopseudo3679 3 ปีที่แล้ว +38

    what is the ':' operator? Great video as usual

    • @JoQeZzZ
      @JoQeZzZ 3 ปีที่แล้ว +18

      The number of bits reserved for the variabele in the field

    • @pseudopseudo3679
      @pseudopseudo3679 3 ปีที่แล้ว +5

      @@JoQeZzZ Cool thank you :D

    • @shawnmatyasovszky7994
      @shawnmatyasovszky7994 3 ปีที่แล้ว +3

      I'd not seen that before either. After reading the replies and doing some digging, I found this if it helps someone else: www.tutorialspoint.com/cprogramming/c_bit_fields.htm

    • @pseudopseudo3679
      @pseudopseudo3679 3 ปีที่แล้ว +4

      @@shawnmatyasovszky7994 sweeeet ill read up thanks

  • @boodeer732
    @boodeer732 2 ปีที่แล้ว +2

    I've been having a hard time to understand how fd_set works while working with accept() function, I couldn't wrap my head around how can they fit many different file descriptors into let's say one singular integer, great video! Thank you so much for your efforts as your videos helped me during all my learning journey.

  • @sergeant_sailor
    @sergeant_sailor ปีที่แล้ว

    Just now implemented my first bit field. Thanks!

  • @10e999
    @10e999 4 ปีที่แล้ว +27

    Maybe too advanced: I like to see a video about code portability:
    For example, bit-field are a wonderful idea to implement protocols in embedded, until you encounter a MCU with different Endianness.

    • @shushens
      @shushens 3 ปีที่แล้ว +2

      What kind of video would that be? A bitfield cannot tell you if it needs endianness conversion. You have to use other means to figure it out. Perhaps a network packet header. Perhaps a cross-compiling toolchain. Not really a bitfield-related problem.

    • @islandcave8738
      @islandcave8738 3 ปีที่แล้ว +3

      You can use bitshifting and bitwise operators on the number 1 to check endiannes, write it out on paper and think about how to do that.
      Once you determine that, you can determine how to convert them to the endianness you need, with more bit shifting operations.

  • @R4ngeR4pidz
    @R4ngeR4pidz 4 ปีที่แล้ว +7

    Love your videos, explaining pretty advanced or obscure techniques in a way that is easy to understand. Keep up the good work :D

  • @BryanChance
    @BryanChance 2 ปีที่แล้ว

    Finally, i finally understand bit fields!! Thank you

  • @ar9iem
    @ar9iem 4 ปีที่แล้ว +2

    Brilliant examples. Thank you Jacob for these tutorials.

  • @montluna2333
    @montluna2333 4 ปีที่แล้ว +2

    Thank you so much! it saves my assignment!

    • @JacobSorber
      @JacobSorber  4 ปีที่แล้ว +1

      You're welcome. Glad I could help.

  • @trestenpool9045
    @trestenpool9045 4 ปีที่แล้ว +2

    You are crazy intelligent. Thank you

  • @tomer2565
    @tomer2565 3 ปีที่แล้ว +1

    Thank you! Exactly what I was looking for

  • @directx872
    @directx872 4 ปีที่แล้ว

    Your videos are so satisfying to watch

    • @JacobSorber
      @JacobSorber  4 ปีที่แล้ว +1

      Thanks. Glad you like them!

  • @sumitbhosale3401
    @sumitbhosale3401 4 ปีที่แล้ว +1

    Nice Explaination Sir. Thank You. Please make video on async or sync in c programming and Waiting for data structures video

  • @nunyobiznez875
    @nunyobiznez875 4 ปีที่แล้ว +1

    Fantastic video, on a very helpful topic. Thank you.

  • @amrgaber4400
    @amrgaber4400 ปีที่แล้ว

    man. I really love you. do you have a full C course on youtube or somthing ?

  • @thejoojoo9999
    @thejoojoo9999 6 หลายเดือนก่อน

    Hey, thanks for this excellent and very clear video.
    I just have one question :
    I understand what you're doing in scenario 2 but I don't understand how it relates to a bitfield. I see you're creating a struct with ints of reduced size, but where is the bitfield ?

  • @ibrahim1ibrahim2
    @ibrahim1ibrahim2 4 ปีที่แล้ว +1

    very informative, keep the good work up

  • @CaptainWumbo
    @CaptainWumbo ปีที่แล้ว

    It's neat. I wonder if it's how APL works under the hood when creating filters. You can imagine it being useful to represent indicies in an array, but probably too much hassel and maybe ultimately slower.

  • @DarkMonsterGFX
    @DarkMonsterGFX 3 ปีที่แล้ว +3

    Hey Jacob! Thanks for the amazing vid, but as another user, there are some topics i find a lil advanced. Can you do a video talking about macros? Thanks again for your stuff :)

    • @JacobSorber
      @JacobSorber  3 ปีที่แล้ว +3

      Sure, I could do that. Are you wanting macro basics, or do you have a specific macro-related question?

  • @flippert0
    @flippert0 10 หลายเดือนก่อน

    Single bit operation came into play when I programmed "bitboards" for a toy chess engine. Wonder how bitfields might have helped here.

  • @raccoon1160
    @raccoon1160 9 หลายเดือนก่อน +1

    Isn't integer overflow UB? I would be careful about saying "it will eventually become negative." I believe __attribute__((packed)) is a non-standard compiler add-on. I would also wrap all the variables in your macros with parentheses just in case you get some operator precedence shenanigans.

  • @69k_gold
    @69k_gold ปีที่แล้ว +1

    I personally don't think there's a need for an option to have multiple set bits. It might end up messing up with other options if it is bitwise-OR'd with them

  • @MrASDewka
    @MrASDewka 3 ปีที่แล้ว +1

    amazing stuff! Thanks a lot!
    Hello from Russia!

    • @JacobSorber
      @JacobSorber  3 ปีที่แล้ว +2

      Hey, thanks! Glad you're enjoying the channel.

  • @KangJangkrik
    @KangJangkrik 3 ปีที่แล้ว +3

    4:28 that ampersand (&) symbol blows my mind
    Usually I have to write like (((options >> 3) & 0x1) == 0x1) and like wow... there is much simple way to do a same thing 😅

    • @VivekYadav-ds8oz
      @VivekYadav-ds8oz 4 หลายเดือนก่อน +2

      Any non-zero value is "truthy", so yeah just checking the option with an & should work.

  • @santoshdasar544
    @santoshdasar544 2 ปีที่แล้ว +1

    Can u make video about bit packing in c

  • @SeriousGamingFreak
    @SeriousGamingFreak 2 ปีที่แล้ว

    thank you for this video

  • @first-thoughtgiver-of-will2456
    @first-thoughtgiver-of-will2456 5 หลายเดือนก่อน

    I wonder if you can switch on all the known combinations if your bitfields are few

  • @aadikarva
    @aadikarva 2 ปีที่แล้ว +1

    Great video explaining this concept. Thanks @Jacob for your video series.
    Comment on example 3 printing, the pattern it prints in your for loop is reverse of how the actual bits are stored in memory conceptually. What if we do:
    for(int i=64; i>0; i--){
    //check if bit is set and print '+' or '.'
    }
    this should print the bits in the LSB to MSB order. Just thought I ask.

    • @charankoppineni4498
      @charankoppineni4498 ปีที่แล้ว

      for(i=63;i>=0;i++) because the IS_SET_BIT macro is defined such a way (counting from 0). LSB and MSB doesn't apply here because there are bits, NOT Bytes.

  • @jadanabil8044
    @jadanabil8044 3 ปีที่แล้ว +1

    How about one video of reading millions of integers from a file into a memory and do some processing on them. For example, an integer number representing one bit of a big giant array... it's a commonly asked interview question and I get stuck everytime 😥

  • @gautamkumarshukla3055
    @gautamkumarshukla3055 3 ปีที่แล้ว

    nice explanation

  • @DanielTredewicz
    @DanielTredewicz 3 ปีที่แล้ว +3

    Aren't 1st and 3rd example usually referred to as masks? I think only the 2nd one is about a bit fields.
    Nonetheless great video as always.

    • @netoskin
      @netoskin 2 ปีที่แล้ว

      Yes, the first time I saw this kind of things was in an assembler book, the chapter on bit masks, but later on my OS class

  • @AlexBlack-xz8hp
    @AlexBlack-xz8hp 2 ปีที่แล้ว

    Awesome!!! Wish I had your videos ages ago when I was first trying to learn this stuff.

  • @nickgennady
    @nickgennady 2 ปีที่แล้ว +1

    Would a bitfield of 100K to million “bools” be faster than c array of same about of bools?

  • @digama0
    @digama0 4 ปีที่แล้ว +2

    Isn't it undefined behavior to overflow a signed int? I don't know if that also applies to bitfield ints but I would assume so...

    • @JacobSorber
      @JacobSorber  4 ปีที่แล้ว +1

      Yes, it is. A pretty good discussion can be found here. I'm also assuming it applies to bit-fields. www.gnu.org/software/autoconf/manual/autoconf-2.63/html_node/Integer-Overflow-Basics.html

    • @digama0
      @digama0 4 ปีที่แล้ว +1

      @@JacobSorber That's... less decisive than I had hoped. I also tried searching this up myself and it seems like no one acknowledges the existence of signed bitfields, much less overflow behavior. Of course it works, it is hard to imagine how you could implement a compiler with any other behavior, but nowadays it is important to make sure it's also in the standard lest your compiler starts deleting code like a madman.

  • @SimonJentzschX7
    @SimonJentzschX7 4 ปีที่แล้ว +1

    great video, but I was thinking the whole time, when should I use flags and when bitfields? What is the performance and portability issue if I use bitfields with 1 bit-sizes?

    • @papasmurf9146
      @papasmurf9146 2 ปีที่แล้ว +1

      A portability issue is whether the bit-field is filled in from least-significant-bit to most-significant or vice-versa. Consider:
      union {
      uint32_t value;
      struct {
      uint32_t a:2;
      uint32_t b:30;
      };
      } var;
      On Linux/Intel, var.a takes the least significant bits of value. On Sun/Sparc they [probably] take the most significant bits (don't have a system handy to test it with). I have seen a bit of code that uses such coding-structures when manipulating standards based formats that have their origins on networks. Usually the structures have conditional compilation depending on the whether or not the LSb or MSb are used first.

  • @lorensims4846
    @lorensims4846 3 ปีที่แล้ว +2

    It was when I conceptually understood the program counter and its relationship with the program status word and its relationship with the actual binary instruction that I felt I really understood exactly how the computer did what it did.
    I'm concerned we've become far too abstracted from the hardware and understanding how it does its work.

    • @newjade6075
      @newjade6075 2 ปีที่แล้ว

      Hi, I just started learning Java and how to use it's apis. But I have no idea how processor and binary instructions work.
      Can you direct me how to learn all these concepts...

    • @lorensims4846
      @lorensims4846 2 ปีที่แล้ว

      @@newjade6075 it was in a systems analysis class after I started out by learning IBM 360/370 Macro Assembly Language and then COBOL in 1980 that I got a clear idea of the binary instruction hitting a recognizer of some sort and the specific bit of the instruction (the op code) actually triggering flags in the “program Status Word”: carry, negative, zero, branch, etc., and the computer responding simply according to how the flags were set. When I looked closely at the bit patterns of the op codes I noticed that the math commands were very similar with only a few bits different, so they always triggered the same flags except a couple depending what the actual operation was. Likewise with the move, compare, branch and other groups of instructions. A clear similarity of the bit patterns with only minor differences.
      I could almost see how the actual bits in a machine language command actually triggered the appropriate flags and thus the response by the computer.
      It was like a vision in my head, hard to describe in words but suddenly it all made sense how a specific binary code would trigger a specific response from a computer. After that all programming made perfect sense, the only problem I say was that people always try to abstract themselves away from this basic truth.
      I prefer to be right down there on the iron.

    • @aadithyaviswanathan6300
      @aadithyaviswanathan6300 2 ปีที่แล้ว

      @@newjade6075 The book "Computer Organisation and Design - the Hardware/Software Interface" by Patterson and Hennessey is an awesome book to understand the same. To understand how the processor is logically implemented using digital gates- "Digital Design" by Morris Mano. The second book in hardware oriented.

  • @SimpleY_
    @SimpleY_ 2 ปีที่แล้ว

    Great tutorial but I wish you explained the &, | and ~ operators!

  • @nickoder4374
    @nickoder4374 2 ปีที่แล้ว

    thanks for video))

  • @benjaminshinar9509
    @benjaminshinar9509 4 ปีที่แล้ว

    great video!

  • @wendolinmendoza517
    @wendolinmendoza517 2 ปีที่แล้ว

    3:43 you did not include the link in the description :(

    • @ayoubmentag9883
      @ayoubmentag9883 2 ปีที่แล้ว

      th-cam.com/video/iX1uGr6Si0E/w-d-xo.html here is the video

  • @McGewen
    @McGewen 2 ปีที่แล้ว

    It is amazing

  • @ArjanvanVught
    @ArjanvanVught 3 ปีที่แล้ว +1

    Very scary macro's at the end; expansion can have very undesired outcome.

  • @jeremyed9507
    @jeremyed9507 11 หลายเดือนก่อน

    Might as well add a FLIP_BIT with ^=

  • @boshydbash9030
    @boshydbash9030 3 ปีที่แล้ว

    agradecido con el de arriba joven

  • @dilawar_uchiha
    @dilawar_uchiha 2 ปีที่แล้ว

    Lovely

  • @eotcoldhymns2930
    @eotcoldhymns2930 4 ปีที่แล้ว +1

    what opensource ide do you use/recommend for c/c++?

    • @BetaChri5
      @BetaChri5 4 ปีที่แล้ว

      i use Mousepad + good old terminal
      no ide need :P

    • @Wahaller
      @Wahaller ปีที่แล้ว +1

      Vim

  • @edgeeffect
    @edgeeffect 11 หลายเดือนก่อน

    Considering C was invented to write an operating system.... I've never understood that it doesn't have binary literals.

  • @cabletvandinternetworldser5409
    @cabletvandinternetworldser5409 4 ปีที่แล้ว

    C program
    Bluetooth socket
    And good package manager

  • @TurboXray
    @TurboXray หลายเดือนก่อน

    Don't EVER use the bit field notation starting at 7:00 into the video, for C/C++. That is processor and compiler dependent, and can get you into trouble. How it's defined under the hood, is not defined in the spec and can/will be different between processors and compilers.

  • @nhanNguyen-wo8fy
    @nhanNguyen-wo8fy 4 หลายเดือนก่อน

    10:55

  • @charankoppineni4498
    @charankoppineni4498 ปีที่แล้ว

    just to be clear, he's counting bits starting from 0 in this program.

  • @nachiketathakur697
    @nachiketathakur697 3 ปีที่แล้ว

    not beginner friendly

  • @afshinahvazi3721
    @afshinahvazi3721 หลายเดือนก่อน

    What does your second example have to do with bit fields? You did a poor job at explaining. Thumbs down.

  • @Ray-ej3jb
    @Ray-ej3jb 4 ปีที่แล้ว

    Way too quick to digest info

    • @JacobSorber
      @JacobSorber  4 ปีที่แล้ว +4

      Sorry it was too fast. Fortunately, TH-cam allows you to replay at reduced speed.

  • @buckworthful
    @buckworthful 2 ปีที่แล้ว +1

    technically speaking (or from language feature perspective), scenario 1 & 3 are not bit fields. They're just normal bit fiddling on a given bit pattern that is of type int