5 ms·
> To beginners it might seem like “wasting memory” by using a 32-bit boolean Maybe I'm a beginner then. He lists a few cases where it's not worse than sticking
by ForkMeOnTinder 3y ago
> To beginners it might seem like “wasting memory” by using a 32-bit boolean
Maybe I'm a beginner then. He lists a few cases where it's not worse than sticking to 8-bit bools, but no cases where it's actually an improvement. It still wastes memory sometimes, e.g. if you have adjacent booleans in a struct, or boolean variables in a function that spill out of registers onto the stack. Sure it's only a few bytes here and there, but why pessimize? What do you gain from using a larger size?
- Quekid5 3y agoComputer architecture is optimized for 32+ bit aligned access to most things. The gain is (usually, but not always!) performance.
- gavinhoward 3y agoI'm afraid you are only slightly correct. Architectures are generally optimized for aligned access (or disallow unaligned access), but what counts as "aligned" is different for each type. A char type that is used for a bool can be accessed on any byte boundary because the alignment of a char is 1. The alignment of a 32-bit value is 4. However, architectures are generally more optimized for 32-bit operations in registers. If you're dealing with a char in a register, the compiler will generally treat it as a 32-bit value, clearing the top bits. (This is one of those places where C's UB can bite you.) However, there are architectures where 32-bit access is optimized.
- deleted 3y ago[deleted]
- tedunangst 3y agoWhat's an example of a function where a boolean variable spills to the stack and the 3 bytes are important?
- gavinhoward 3y agoAnd to add to that, if you use an actual bool type, sanitizers will warn you if they are ever any value other than false (0) or true (1).
- defrost 3y agoIt depends entirely on the architectures | CPUs, that said the obvious case from past experience is numeric processsing jobs where (say) you flow data into "per cycle" structs that lead with some conditionals and fill out with (say) 512 | 1024 | 2048 sample points for that cycle (32 or 64 bit ints or floats) .. the 'meat' of the per cycle job. My specific bug bear here was a junior who insisted "saving space" by packing the structs and using a single 8 bit byte for the conditionals. Their 'improved' code ground throughput on intel chips by a factor of 10 or so and generated BUS ERRORs on SPARC RISC architectures. By packing the header of the structs they misaligned the array of data values such that the intel chips were silently fetching two 32 bit words (say) to get half a word from each to splice together to form a 32 bit data value (that was passed straddling a word boundary) to pipe into the ALU and then do something similar to repack on the other end - SPARC's quite sensibly were throwing a fit at non aligned data. Point being - sometimes it makes sense to fit data to the architecture and not pack data to "save" space (this is all for throughput piped calculations not long term file storage in any case)
- xvedejas 3y agoThis is the use case for `uint_fast8_t` (part of the C99 standard); it should use whatever width of unsigned integer is enough to store a byte, but fastest for the platform. You always know that the type can be serialized as 8 bits, but it might be larger in memory. So long as you don't assume too much about your struct sizes across platforms, it should be a good choice for this. Although, if alignment is an issue, it might be a bit more complicated depending on platform.
- stefan_ 3y ago10 years ago when ATmegas were still around and your 32 bit variable was generating 3 instructions for addition I would say „right on“ but now everything is a 32 bit Cortex-M and please stop polluting your code with this nonsense
- paulddraper 3y agoIDK it seems semantically right
- eyegor 3y agoMost of the time an easy optimization is to pad fields of your struct to a 32 bit boundary. Almost any compiler will do this for you (look up "struct alignment / padding"). If the compiler is going to do this anyway, might as well use the memory yourself instead of letting it be empty space. If it doesn't happen, you leave performance on the table, so doing this raises the chance that your struct/fields will be aligned. Nuance is that each field should be at an address divisible by the fields size or wordline size, not some magic 32 constant. The entire struct should also be padded to a multiple of the largest fields size. In practice this usually means 32 bit alignment. Ref http://www.catb.org/esr/structure-packing/ http://www.catb.org/esr/structure-packing/