• @KindaABigDyl@programming.dev
    link
    fedilink
    1852 months ago
    typedef struct {
        bool a: 1;
        bool b: 1;
        bool c: 1;
        bool d: 1;
        bool e: 1;
        bool f: 1;
        bool g: 1;
        bool h: 1;
    } __attribute__((__packed__)) not_if_you_have_enough_booleans_t;
    
    • @xthexder@l.sw0.com
      link
      fedilink
      41
      edit-2
      2 months ago

      Or just std::bitset<8> for C++. Bit fields are neat though, it can store weird stuff like a 3 bit integer, packed next to booleans

      • Sonotsugipaa
        link
        fedilink
        English
        10
        edit-2
        2 months ago

        That’s only for C++, as far as I can tell that struct is valid C

    • @h4x0r@lemmy.dbzer0.com
      link
      fedilink
      English
      162 months ago

      This was gonna be my response to OP so I’ll offer an alternative approach instead:

      typedef enum flags_e : unsigned char {
        F_1 = (1 << 0),
        F_2 = (1 << 1),
        F_3 = (1 << 2),
        F_4 = (1 << 3),
        F_5 = (1 << 4),
        F_6 = (1 << 5),
        F_7 = (1 << 6),
        F_8 = (1 << 7),
      } Flags;
      
      int main(void) {
        Flags f = F_1 | F_3 | F_5;
        if (f & F_1 && f & F_3) {
          // do F_1 and F_3 stuff
        }
      }
      
      • @anotherandrew@lemmy.mixdown.ca
        link
        fedilink
        English
        1
        edit-2
        2 months ago

        Why not if (f & (F_1 | F_3)) {? I use this all the time in embedded code.

        edit: never mind; you’re checking for both flags. I’d probably use (f & (F_1 | F_3)) == (F_1 | F_3) but that’s not much different than what you wrote.

    • @mmddmm@lemm.ee
      link
      fedilink
      1572 months ago

      And compiler. And hardware architecture. And optimization flags.

      As usual, it’s some developer that knows little enough to think the walls they see around enclose the entire world.

      • Lucien [he/him]
        link
        fedilink
        142 months ago

        Fucking lol at the downvoters haha that second sentence must have rubbed them the wrong way for being too accurate.

      • @timhh@programming.dev
        link
        fedilink
        22 months ago

        I don’t think so. Apart from dynamically typed languages which need to store the type with the value, it’s always 1 byte, and that doesn’t depend on architecture (excluding ancient or exotic architectures) or optimisation flags.

        Which language/architecture/flags would not store a bool in 1 byte?

        • @brian@programming.dev
          link
          fedilink
          22 months ago

          things that store it as word size for alignment purposes (most common afaik), things that pack multiple books into one byte (normally only things like bool sequences/structs), etc

          • @timhh@programming.dev
            link
            fedilink
            11 month ago

            things that store it as word size for alignment purposes

            Nope. bools only need to be naturally aligned, so 1 byte.

            If you do

            struct SomeBools {
              bool a;
              bool b;
              bool c;
              bool d;
            };
            

            its 4 bytes.

            • @brian@programming.dev
              link
              fedilink
              21 month ago

              sure, but if you have a single bool in a stack frame it’s probably going to be more than a byte. on the heap definitely more than a byte

              • @timhh@programming.dev
                link
                fedilink
                01 month ago

                but if you have a single bool in a stack frame it’s probably going to be more than a byte.

                Nope. - if you can’t read RISC-V assembly, look at these lines

                        sb      a5,-17(s0)
                ...
                        sb      a5,-18(s0)
                ...
                        sb      a5,-19(s0)
                ...
                

                That is it storing the bools in single bytes. Also I only used RISC-V because I’m way more familiar with it than x86, but it will do the same thing.

                on the heap definitely more than a byte

                Nope, you can happily malloc(1) and store a bool in it, or malloc(4) and store 4 bools in it. A bool is 1 byte. Consider this a TIL moment.

                • @brian@programming.dev
                  link
                  fedilink
                  21 month ago

                  c++ guarantees that calls to malloc are aligned https://en.cppreference.com/w/cpp/memory/c/malloc .

                  you can call malloc(1) ofc, but calling malloc_usable_size(malloc(1)) is giving me 24, so it at least allocated 24 bytes for my 1, plus any tracking overhead

                  yeah, as I said, in a stack frame. not surprised a compiler packed them into single bytes in the same frame (but I wouldn’t be that surprised the other way either), but the system v abi guarantees at least 4 byte alignment of a stack frame on entering a fn, so if you stored a single bool it’ll get 3+ extra bytes added on the next fn call.

                  computers align things. you normally don’t have to think about it. Consider this a TIL moment.

        • @mmddmm@lemm.ee
          link
          fedilink
          02 months ago

          Apart from dynamically typed languages which need to store the type with the value

          You know that depending on what your code does, the same C that people are talking upthread doesn’t even need to allocate memory to store a variable, right?

            • @timhh@programming.dev
              link
              fedilink
              21 month ago

              I think he’s talking about if a variable only exists in registers. In which case it is the size of a register. But that’s true of everything that gets put in registers. You wouldn’t say uint16_t is word-sized because at some point it gets put into a word-sized register. That’s dumb.

  • pelya
    link
    fedilink
    332 months ago

    std::vector<bool> fits eight booleans into one byte.

    • TimeSquirrel
      link
      fedilink
      82 months ago

      std::vector<std::vector<bool>> is how I stored the representation of a play field for a Tetris game I made once.

    • @borokov@lemmy.world
      link
      fedilink
      22 months ago
      auto v = std::vector<bool>(8);
      bool* vPtr = v.data;
      vPtr[2] = true;
      // KABOOM !!!
      

      I’ve spent days tracking this bug… That’s how I learned about bool specialisation of std::vector.

  • @SW42@lemmy.world
    link
    fedilink
    222 months ago

    Joke’s on you, I always use 64 bit wide unsigned integers to store a 1 and compare to check for value.

  • Lucy :3
    link
    fedilink
    912 months ago

    Then you need to ask yourself: Performance or memory efficiency? Is it worth the extra cycles and instructions to put 8 bools in one byte and & 0x bitmask the relevant one?

    • Nat (she/they)
      link
      fedilink
      232 months ago

      A lot of times using less memory is actually better for performance because the main bottleneck is memory bandwidth or latency.

      • Cethin
        cake
        link
        fedilink
        English
        82 months ago

        Yep, and anding with a bit ask is incredibly fast to process, so it’s not a big issue for performance.

      • @timhh@programming.dev
        link
        fedilink
        22 months ago

        It’s not just less memory though - it might also introduce spurious data dependencies, e.g. to store a bit you now need to also read the old value of the byte that it’s in.

        • @anton@lemmy.blahaj.zone
          link
          fedilink
          32 months ago

          It might also introduce spurious data dependencies

          Those need to be in the in smallest cache or a register anyway. If they are in registers, a modern, instruction reordering CPU will deal with that fine.

          to store a bit you now need to also read the old value of the byte that it’s in.

          Many architectures read the cache line on write-miss.

          The only cases I can see, where byte sized bools seems better, are either using so few that all fit in one chache line anyways (in which case the performance will be great either way) or if you are repeatedly accessing a bitvector from multiple threads, in which case you should make sure that’s actually what you want to be doing.

        • Nat (she/they)
          link
          fedilink
          11 month ago

          Could definitely be worse for latency in particular cases, but if we imagine a write heavy workload it still might win. Writing a byte/word basically has to do the same thing: read, modify write of cache lines, it just doesn’t confuse the dependency tracking quite as much. So rather than stalling on a read, I think that would end up stalling on store buffers. Writing to bits usually means less memory, and thus less memory to read in that read-modify-write part, so it might still be faster.

  • @kiri@ani.social
    link
    fedilink
    22
    edit-2
    2 months ago

    I have a solution with a bit fields. Now your bool is 1 byte :

    struct Flags {
        bool flag0 : 1;
        bool flag1 : 1;
        bool flag2 : 1;
        bool flag3 : 1;
        bool flag4 : 1;
        bool flag5 : 1;
        bool flag6 : 1;
        bool flag7 : 1;
    };
    

    Or for example:

    struct Flags {
        bool flag0 : 1;
        bool flag1 : 1:
        int x_cord : 3;
        int y_cord : 3;
    };
    
    • @lapping6596@lemmy.world
      link
      fedilink
      32 months ago

      I watched a YouTube video where a dev was optimizing unity code to match the size of data that is sent to the cpu using structs just like this.

    • @Gsus4@mander.xyz
      link
      fedilink
      11
      edit-2
      2 months ago

      Weird how I usually learn more from the humor communities than the serious ones… 😎

  • @steeznson@lemmy.world
    link
    fedilink
    82 months ago

    We need to be able to express 0 and 1 as integers so that functionality is just being overloaded to express another concept.

    Wait until the person who made this meme finds out about how many bits are being wasted on modern CPU architectures. 7 is the minimum possible wasted bits but it would be 31 on every modern computer (even 64b machines since they default to 32b ints).

  • @Skullgrid@lemmy.world
    link
    fedilink
    162 months ago

    just like electronic components, they sell the gates by the chip with multiple gates in them because it’s cheaper

  • @mavu@discuss.tchncs.de
    link
    fedilink
    122 months ago

    This reminds me that I actually once made a class to store bools packed in uint8 array to save bytes.

    Had forgotten that. I think i have to update the list of top 10 dumbest things i ever did.

  • Tekhne
    link
    fedilink
    142 months ago

    Are you telling me that no compiler optimizes this? Why?

    • @timhh@programming.dev
      link
      fedilink
      242 months ago

      Well there are containers that store booleans in single bits (e.g. std::vector<bool> - which was famously a big mistake).

      But in the general case you don’t want that because it would be slower.

    • @Anders429@programming.dev
      link
      fedilink
      352 months ago

      It would be slower to read the value if you had to also do bitwise operations to get the value.

      But you can also define your own bitfield types to store booleans packed together if you really need to. I would much rather that than have the compiler do it automatically for me.

    • @gamer@lemm.ee
      link
      fedilink
      5
      edit-2
      2 months ago

      Consider what the disassembly would look like. There’s no fast way to do it.

      It’s also unnecessary since 8 bytes is a negligible amount in most cases. Serialization is the only real scenario where it matters. (Edit: and embedded)

      • @Croquette@sh.itjust.works
        link
        fedilink
        52 months ago

        In embedded, if you are to the point that you need to optimize the bools to reduce the footprint, you fucked up sizing your mcu.