• skisnow@lemmy.ca
    link
    fedilink
    English
    arrow-up
    52
    ·
    1 day ago

    Back in the day when it mattered, we did it like

    #define BV00		(1 <<  0)
    #define BV01		(1 <<  1)
    #define BV02		(1 <<  2)
    #define BV03		(1 <<  3)
    ...etc
    
    #define IS_SET(flag, bit)	((flag) & (bit))
    #define SET_BIT(var, bit)	((var) |= (bit))
    #define REMOVE_BIT(var, bit)	((var) &= ~(bit))
    #define TOGGLE_BIT(var, bit)	((var) ^= (bit))
    
    ....then...
    #define MY_FIRST_BOOLEAN BV00
    SET_BIT(myFlags, MY_FIRST_BOOLEAN)
    
    
    • ethancedwards8@programming.dev
      link
      fedilink
      English
      arrow-up
      3
      ·
      18 hours ago

      Okay. Gen z programmer here. Can you explain this black magic? I see it all the time in kernel code but I have no idea what it means.

      • skisnow@lemmy.ca
        link
        fedilink
        English
        arrow-up
        4
        ·
        10 hours ago

        The code is a set of preprocessor macros to stuff loads of booleans into one int (or similar), in this case named ‘myFlags’. The preprocessor is a simple (some argue too simple) step at the start of compilation that modifies the source code on its way to the real compiler by substituting #defines, prepending #include’d files, etc.

        If myFlags is equal to, e.g. 67, that’s 01000011, meaning that BV00, BV01, and BV07 are all TRUE and the others are FALSE.

        The first part is just for convenience and readability. BV00 represents the 0th bit, BV01 is the first etc. (1 << 3) means 00000001, bit shifted left three times so it becomes 00001000 (aka 8).

        The middle chunk defines macros to make bit operations more human-readable.

        Calling SET_BIT(myFlags, MY_FIRST_BOOLEAN) gets turned into ((myFlags) |= ((1 << 0))) , which could be simplified as myFlags = myFlags | 00000001 . (Ignore the flood of parentheses, they’re there for safety due to the loaded shotgun nature of the preprocessor.)

      • NιƙƙιDιɱҽʂ@lemmy.world
        link
        fedilink
        arrow-up
        4
        ·
        edit-2
        14 hours ago

        It’s called bitshifting and is used to select which bits you want to modify so you can toggle them individually.

        1 << 0 is the flag for the first bit
        1 << 1 for the second
        1 << 2 for the third and so on

        I think that’s correct. It’s been years since I’ve used this technique tbh 😅

    • Quatlicopatlix@feddit.org
      link
      fedilink
      arrow-up
      9
      ·
      1 day ago

      With embedded stuff its still done like that. And if you go from the arduino functionss to writing the registers directly its a hell of a lot faster.