How do I access a single bit?

แชร์
ฝัง
  • เผยแพร่เมื่อ 9 ต.ค. 2023
  • Patreon ➤ / jacobsorber
    Courses ➤ jacobsorber.thinkific.com
    Website ➤ www.jacobsorber.com
    ---
    How do I access a single bit? // Bitwise operations can be a bit frustrating for new programmers. This video shows you a few ways to access a single bit, usually within a bitfield or bitvector.
    Related Videos:
    Bit Fields: • Bit Fields in C. What ...
    ***
    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.jacobsorber.com
    people.cs.clemson.edu/~jsorber/
    persist.cs.clemson.edu/
    To Support the Channel:
    + like, subscribe, spread the word
    + contribute via Patreon --- [ / jacobsorber ]
    Source code is also available to Patreon supporters. --- [jsorber-youtube-source.heroku...]

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

  • @filips7158
    @filips7158 8 หลายเดือนก่อน +84

    A passer-by note : in C, you are only technically suppesed to do bitwise operations on unsigned integer types. Signed integer type behavior is signedness implementation specific. Most coding standards will shed a tear if you do this. They will even make you specifically declare your constants as unsigned. I personally allways fall back to unsigned types and use signed types only when necessary. Just saves me a lot of trouble in general.

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

      I think with C23 negative number representation gets standardized to 2s-complement and with that a lot of signed value behavior should get standardized as well, but I might be wrong.

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

      @@esdel I sure hope you're wrong. That would reduce C's portability because then the behavior will have to be explicitly redefined for 1's complement machines.

    • @xhivo97
      @xhivo97 8 หลายเดือนก่อน +3

      @@anon_y_mousse 2's complement is in C23. 1's complement machines exist? (I realize you might have been sarcastic on that one lol)

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

      @@xhivo97 They're old and rare, but they do exist. It's just that this will be a constant craw in my beak when I try to tout the portability of C and proponents of every other language will point this out with glee even though C will still compile for such computers and many more that their language of choice won't work on and it'll irritate me. It's tough being one of a small handfuls of C proponents. Only makes it worse that now I hear they're adding constexpr to C. If they're just going to copy every C++ feature then I can't finish my own language fast enough.

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

      @@anon_y_mousse IDK what to tell, other than use an older compiler or -std=c89 if you must... Could you explain _why_ those are bad? Backwards compatibility with archaic machines is a not a good reason to hold on from having good features. I don't mean to be rude, but after some light searching I couldn't find any such machine, do you mind naming one for my own curiosity? I would be more concerned about potential UB when subtracting when on 2's complement.
      Like it or not the majority of C's issues could be made less bad with language features that play well with static analyzers and runtime sanitizers; VLA syntax which has been a (optional?) thing since c99 gives you a bit better bounds checking when using a sanitizer, constexpr would also provide some static checking benefits I imagine but I've never used such a feature so am not quite sure. But I'm sure the C standard is in good hands and you gotta move on with the times at some point.

  • @hampus23
    @hampus23 8 หลายเดือนก่อน +6

    Keep up the excellent work with your educational content! 🙌

  • @osamaadil231
    @osamaadil231 8 หลายเดือนก่อน +5

    Very informative! Keep up the good work ❤

  • @cusematt23
    @cusematt23 8 หลายเดือนก่อน +6

    I’ve watched like 50 of your videos this week. Great stuff.

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

    Top tier content! You are a true OG!

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

    wow that was a goood one. THANKS!!!!

  • @deepakr8261
    @deepakr8261 8 หลายเดือนก่อน +2

    How about the union method Dr Sorber? So assume the example of a 32 bit register with each bit having specific purposes.
    So you can define something as below:
    union {
    uint32_t num;
    struct {
    uint8_t a:1; // bit indicates something else
    uint8_t b:1; //1 bit indicating something
    uint8_t c:2; //2 bits indicating something
    ...
    }fields;
    }reg;
    So say you read the 32 bit register into num as
    reg.num = (volatile uint32_t *) (address)
    and then to access individual bits you can simply do
    reg.fields.a
    or
    reg.fields.b etc

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

      The order of bit fields is not specified by the C standard. This method may work on one compiler, fail on another one, and break on the next version of the compiler where it used to work.

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

      @@edgarbonet1 From the c99 standard "An implementation may allocate any addressable storage unit large enough to hold a bit-field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit." In this case, the storage unit is uint32_t as set by the union

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

      @@deepakr8261 The bit fields are indeed adjacent. The order of allocation, however, is implementation defined. You could expect a consistent order only if the platform's ABI specifies it.

  •  8 หลายเดือนก่อน +5

    Would be interesting what the compiler does.
    If I write x & (0x1 n) & 0x1 with the example above.

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

      it depends on the compiler, really. I've seen both happen, in different scenarios with the same compiler even.

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

      Any half-decent compiler knows how to do constant folding. Thus, if n is a compile-time constant, 0x1

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

    Great video as always. Thank you

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

    What's the typeface you've used for the text on screen?

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

    Very useful video and good explanation. But i would have liked to get into more detail, for example explain how to change just one bit.
    Bit still great video and thanks for the content

    • @pumpkinhead002
      @pumpkinhead002 8 หลายเดือนก่อน +2

      To set a bit to 1 you would create a mask of all zero and the bit to set equal to 1. Then you would logically OR "|" the mask with whichever variable that you want to set.
      If you want to set the bit to 0, then you would invert the mask you made above, such that the but to set is a 0 and the bits you want to keep are 1, then you AND the mask with your variable to set the bit to zero.

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

      Creel has a video "Bit Hacks from Beginner to Advanced" with some nice visualizations.

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

    Nice

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

    Do you recommend that method of looping from the end, rather than starting at the end and then i--?

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

    What's the advantage/disadvantage of using defines to create the bitmasks? Can't that also be done using an enum?

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

    I made a function to return a string of that binary, and the result was always empty, cause it was composing the string of only 0 or 1 as int, so empty characters, took me 15 min to find the bug.
    It made me learn that you can convert a 0 or 1 (as an int) to a char very easily by adding 48 cause 48+0=48 which is '0' in ASCII and 48+1=49 which is '1' in ASCII.

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

      Don't add 48, add '0'. Yes, “'0'” is just another way of writing “48”, but writing it as a character constant makes the programmer's intent clearer, which is important in the long run.

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

    Considering that most ISAs have a simple bit set/reset instruction... it always annoys me how complex and unintuitive it is in nearly all high level languages... but I AM a huge assembly language enthusiast and snob.

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

      The AVR instruction set has the instructions “Set Bits in Register” and “Clear Bits in Register”. However, if you look at their binary encodings, you realize that these are merely aliases for “Logical OR with Immediate” and “Logical AND with Immediate”. These aliases are just hiding the bitwise boolean operations in the same manner as the macro used in this video.

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

    my guess before watching: bit shift so your desired bit is at 0th position, AND with 1 and then you can check if your value is 0 or 1?

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

    Which editor do you use for programming?

    • @errodememoria
      @errodememoria 8 หลายเดือนก่อน +2

      The one in the video is VSCode

  • @matiasm.3124
    @matiasm.3124 8 หลายเดือนก่อน

    Nice video as always..but i don't get why you have to finish with & 0x1 in the printf or the macro when you do the bitwise..

    • @marwan7614
      @marwan7614 8 หลายเดือนก่อน +7

      Let's say you have :
      00001010
      ^
      To check the second bit you first shift so to the right by one so >> 1 then it becomes:
      00000101
      ^
      But then you have an extra bit so to get rid of it you do an AND(&) operation so
      00000101
      &
      00000001
      =
      00000001
      Then only the first bit is left if was 0 the the result would be 00000000
      Btw 0x1 = 00000001

    • @matiasm.3124
      @matiasm.3124 8 หลายเดือนก่อน +1

      @@marwan7614 very nice explained.. thanks for your time.

  • @user-ke7yn6ru5e
    @user-ke7yn6ru5e 8 หลายเดือนก่อน

    Could you make a video about nan in c?

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

      What about it?

  • @artem.pirkhal
    @artem.pirkhal 8 หลายเดือนก่อน

    Hi Jacob. Many thanks for your work.
    Could you explain, how does delete operator knows exactly how many memory we allocated by new operator, and how we can repeat this logic for malloc/free functions in C?
    I tried to get shifted pointer to sizeof(size_t) bytes before actual pointer and find that we have strange number which is pretty much allows us to know how big chunk was allocated but for my machine it was never lower than 33 bytes even if I requested single sizeof(int ) memory. So I have question: why this allocated block is always has size so much bigger than was requested and why this size always follows condition (size % 2 == 1)? I mean why this lower bit is always(?) equals 1. Short code example below
    void *p = malloc(sizeof(void));
    size_t *ph = (size_t *)p - 1;
    printf("size: %lu
    ", *ph);

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

      As far as I know, there's no official way in C or C++ to get the amount of allocated memory. Each standard library in each OS can do it a different way. What you do here is undefined behaviour (i.e. it may work for you but it can probably fail for someone else). If you want to ensure you always know the allocated length, you have to write replacements of malloc and free yourself which allocate one extra size_t where you store the length, where you return the pointer next to this number, and where you calculate the previous one before calling the actual free.

    • @artem.pirkhal
      @artem.pirkhal 8 หลายเดือนก่อน

      @@DiThi Yep. I know it. But I still want to know why memory header ((size_t *)ptr - 1) contains this weird number 33, 49, 65, 81, 129? For what purpose this lower bit set in 1? Does it means that next 32, 48, 64, 80, 128 bytes was allocated? Then why it doesn't switch to 0 after we free this memory? I just want to know what this header value means. I tried to find this information but I'm still here... I hope you, Or Jacob could help me?

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

      @@artem.pirkhal operating systems don't allocate ranges of bytes, they allocate entire pages (in most systems that's 4kb). So malloc and friends keep track of used memory within those pages in some other way, like storing the size of the allocated memory at the beginning of each chunk. I just checked that code in my system (linux) and I get the same result, some odd number multiple of 16 + 16 + 1. My guess is that it's actually not the size, but a combination of the size and some flags. That extra 1 is probably some flag with a different meaning. Since it's always aligned to 16 bytes, it doesn't need the lower 4 bits, so it's zeroed out and used for other purposes. I accidentally corroborated this by adding more parameters than arguments to printf, which prints internal CPU registers and one of them is the length without the extra +1.
      It's probably not set to zero because it's likely keeping small freed buffers around to give when requesting another malloc, so it doesn't waste time calculating stuff.

    • @artem.pirkhal
      @artem.pirkhal 8 หลายเดือนก่อน

      @@DiThi Make sense. But using overloading of new/delete we are able to track memory allocation in C++. Sad that we don't have this abilities in C. Only by making custom allocation/freeing macros or function overloading. Interesting to know, how that implemented in C++

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

      @@artem.pirkhal We can certainly do that in C as well. There's many custom allocators, but the simplest way to do it in your application is just by doing e.g. #define malloc(x) my_malloc(x), and from your malloc you can call the original one. Of course the macros must either come after their definition or not be present at all in its own .c file, otherwise you can't call the original malloc. Unless you use their alternate names. E.g. in linux glibc we have __glibc_malloc and __glibc_free.

  • @baguettedad
    @baguettedad 8 หลายเดือนก่อน +7

    But instead of a macro, wouldn't it be easier to use enums for the same purpose?
    Great video btw!

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

      Why not both?

    • @baguettedad
      @baguettedad 8 หลายเดือนก่อน +3

      @@MechPaul macros can be a pain to debug

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

      You mean to define the bit constants?

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

      not really, since the idea of bitfields is encompassing 8 independent properties of something. there are 2^8 states possible, which you would have to define individually as an enum. It's just not the appropiate structure.

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

      @@zokalyx enum { foo = 0x1, bar = 0x2, gib = 0x4, gab = 0x8, bob = 0x10..., comboX = foo | bar, comboY = foo | gib | gab, };
      Simply specifying tokens and their values.
      One doesn't need to fill in 256 (or more) using the default 'auto increment' feature of enum's.

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

    It would be great if we could purchase your C course from somewhere instead of juggling from youtube videos

  • @etiennepretorius1993
    @etiennepretorius1993 8 หลายเดือนก่อน +10

    What about a bit field in a struct?

    • @bloom945
      @bloom945 8 หลายเดือนก่อน +5

      I like this a lot more since you can make it super clear what everything is. For the same reason I tend to prefer enums over macros for bitflags.

    • @rexjuggler19
      @rexjuggler19 8 หลายเดือนก่อน +10

      You beat me to it. You can address bits using a structure which might be a bit easier. struct {
      unsigned readonly : 1;
      unsigned hidden : 1;
      unsigned system : 1;
      unsigned volumelabel : 1;
      unsigned subdirectory : 1;
      unsigned archive : 1;
      unsigned bitSix : 1;
      unsigned bitSeven : 1;
      } fatByte

      fatByte.readonly = 1
      fatByte.hidden = 1
      fatByte.system = 0
      fatByte.volumelabel = 0
      fatByte.subdirectory = 1
      fatByte.archive = 0
      A good example of using bit fields would be for GPIO access on devices like raspberry Pis to activate LEDs etc.

    • @hoffiee123
      @hoffiee123 8 หลายเดือนก่อน +3

      @@rexjuggler19 I agree, and that together with unions you can easily pass it between interfaces which doesn't use bit fields without having to do some type casting

    • @gosnooky
      @gosnooky 8 หลายเดือนก่อน +3

      This is the way

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

      The problem with bitfields is that the order is undefined.
      As in that is undefined if the first bit is bit zero or not

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

    A bit of bikesheding here: why are you (still) using `void` in an otherwise empty parameter list (here of the main function)?

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

      old habits? 🤔

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

      ​@@JacobSorber No offense intended, I was just curious. Thx for your reply!

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

      @@bsdooby none taken. it's a good reminder.

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

    instead of 0x just use 0b

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

    When you provided ARCHIVE value, shouldn't it be a 0xA instead of 0x10?

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

      No:
      - 0xA is decimal 10, binary 1010
      - 0x10 is decimal 16, binary 10000.

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

      @@edgarbonet1Right, 0xA would set two flags at once. My bad.

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

    Drop the shirt link

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

    A thing I like to do, is instead of writing the bitmasks in HEX, I often write them in binary. Basically anytime if I feel the need to comment the binary after

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

      C doesn't support binary literals. That is a GCC implementation.

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

      @@pumpkinhead002 C23 includes binary literals that works similarly to the one in C++. Apostrophes (') can also be used as digit separators. Here's an example:
      0b'0000'0000'0000'0000

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

      And especially if you are using 64 bit types, writing out all bits on their own will be less useful IMO because counting the positions is harder than learning how to read hex.

  • @zxuiji
    @zxuiji 8 หลายเดือนก่อน +12

    Shouldn't teach people to hard code values like 8 bits, we have CHAR_BIT, should use every time to teach people to be in the habit of using adaptable macros instead of hard coded values. The people who learnt to hard code 8 bits as the length of bytes will surely in the future encounter situations where they will have to go through their whole code base replacing that value because of that bad assumption (granted 9 times outa 10 it will be because of old systems that they need to but there's surely research systems etc that use bigger values too)

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

      Find me a machine made after the 486 where the value is different

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

      @@casperes0912 Does that stop the older machines from existing?

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

      @@casperes0912 I'm not a researcher (well not a professional one anyways) so I don't know what machines there are with it different but then there are dumbass data modals like SILP64, what's to stop some research facility ordering a custom computer where it's different? What's to stop them then using any of the software available to the public on said machine? The art of programming is to throw out every assumption you can, no ifs, buts or whats about it, just throw them out.

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

      ​@@casperes0912Lots of signal processing CPUs aka DSP are not byte oriented. They often have 12 or 16 as CHAR_BIT. And yes, even new ones.

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

      I’ll use avx without any runtime checks

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

    How to toggle a single bit ?

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

      Use the C bitwise NOT operator ~

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

      @@johngangemi1361No, use ^ (xor)

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

    Not many youtubers are making C videos these days, so I really, really appreciate you are spending time to make them.
    However for a C learner like me, the videos are made in a way that are very zappy to me and the you are talking very, very fast. But maybe the audience you aim are more experienced and much better to English, than me. From a pedagogical view, I think, there are to much information on the screen. The code is only using about half of the screen space and the music is just noise and totally irrelevant to me. Prerequisites knowledge for the video will also be very fine.
    The best learning videos for me, just start immediately.

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

      I agree mostly, but these are level 200 and expect some familiarity. He is publishing for his students and similar. There are other introductory C Lang videos available.

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

      ​@@TreeLuvBurdpu We all have our preferences and I consider myself at a medium level. The best C Teacher I know is Kris Jordan: th-cam.com/play/PLKUb7MEve0TjHQSKUWChAWyJPCpYMRovO.html

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

      @@TreeLuvBurdpu More than two hours of exellent C talk with no noice and from level 0 to at least level 200, I think. How I program C with Eskild Steeberg: th-cam.com/video/443UNeGrFoM/w-d-xo.html

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

      As a non-native English speaker, I do find the speech a bit fast at times. However, his articulation is very clear, so it is easy to follow nevertheless. You may try slowing down the video if you are struggling.

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

      @@edgarbonet1 I agree, but I also oppose irrelevant noises e.g. music and fancy video editing. Also I don't need to know, which IDE that is used, but just the code.

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

    In many cases it’s more accurate to say computers represent everything in sexaquinquabicentesrmal, not binary. But nobody wants to say that partly because *simplified* computers do use binary and partly because, well, do *you* want to regularly pronounce that?

    • @maxaafbackname5562
      @maxaafbackname5562 8 หลายเดือนก่อน +2

      No idea what numberingsystem you are referring to.
      Google can't find anything about it.
      Is it something like 64?
      In some sense you are correct, there are 64 wordsizes, but also other wordsizes, like 32 or even not a power of two.
      So saying that computers are "that" is already incorrect.
      But a "computer" can do more than operating on a whole word, like the arithmetic instructions.
      Enough instructions operatate on a single bit or on separate bits in a word.
      Further more: at the hardware level, only two levels are used.
      These levels are encoded as 0 and 1.
      Another way to say that computers use binary.

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

      @@maxaafbackname5562 Base 256. Pretty much everything operates on a byte at a time and we have byte-addressable RAM not bit-addressable RAM.

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

      It's a good thing that bases that are powers of 2 are trivial to convert between!
      Imagine dealing with base 256, but you have to use a unique symbol for each value...

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

      @@HansLemurson Yeah, often binary is easier to work with because of that. Just it sometimes helps to think of what the computer is doing as operating on a byte at a time.

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

      @@danielrhouck I like how Hexadecimal strikes a balance between not having to use too many digits, but also not having too many distinct values. 16 values is easy to wrap your brain around.
      How computers actually process the data though can vary from machine to machine. I remember building a redstone calculator in minecraft using comparators which was actually _natively_ hexadecimal, since there are 16 different signal strength values.
      In modern electronic computers, memory-access is byte-aligned, but data is read into the processor in multi-byte words, so when you just want to look at a single byte you have to load 4, and then ignore 3 of them.

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

    I would usually do [sharp]define BITVALUE(X, N) !!((X) & 1

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

    Can combine the #defines like this? -> READONLY | HIDDEN

    • @maxaafbackname5562
      @maxaafbackname5562 8 หลายเดือนก่อน +4

      Yes, because there are no overlapping bits in the definitions.

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

      Definitely. Thanks!

    • @rustycherkas8229
      @rustycherkas8229 8 หลายเดือนก่อน +2

      Yes, but you need to take care.
      #define b0 (1u