Why use bool32 in stead of bool?

Just wondering why bool32 is used in stead of bool?
It is a way of differentiating whether we are looking for a result of 0 or 1, or if we are looking for a result of 0 or not 0. For Casey's explanation, you can find it on day 007, if you look at it on this website under "Episode Guide" click on Day 007 - Initializing Direct Sound and you have it on the "Bool datatype idiosyncraries (9:21)" link.
To inline some of the reasons here...

If you want to check if a flag with bit-pattern 00001000 is set in 00101001 you can apply the AND operator to them and get 00001000 as result. That tells you that the flag is set if you do a test whether the result is non-zero. We never actually force the value of the comparison to 0 or 1 exactly. Therefore we make the comparison more efficient, especially if it's used throughout a whole codebase.
Sorry for bringing this old topic back up. I am wondering if anybody ever made any measurements about the performance impact of the C++ bool type forcing the values to be either 0 or 1. I don't think it should be, because any comparison operators (==, !=, <, >, ...) and any boolean operators (&&, ||) return either 0 or 1 anyways. So the only ways I can imagine how one would get bool32 values that are something other than 0 or 1 is by doing bitwise operations. So how much is saved by this depends on how often those happen. And of course how the compiler optimizes this. I'd love to see some actual numbers on this...

Also with an generic integer as bool type one has to be careful not to get false negatives due to truncation if working together with bigger types:

1
2
3
4
5
int64 value = UINT32_MAX + 1;
bool32 asBool = value;
if (asBool) {
    // WIll not enter if, asBool == 0!
}
Your compiler should be giving you a warning that you are assigning a value that is too big to fit into assignment slot.

This bug should never be happening.
I actually recommend against using "bool" for a number of reasons, some of which are mentioned here, but some of which aren't.

One very important one is that it is not clear how big "bool" is, whereas it is very clear how big "bool32" is, and generally I like to make sure that I know the sizes of everything that I put in my structures. So using "bool32" habitually is much nicer, I find, that using "bool", which is too ambiguous for my tastes.

In my actual code (not on stream), I use "x" types as well, so I have bool32x which means "an integer value that is at least 32 bits wide, but might be more, and which is only used as a zero or non zero value". Etc., etc.

Performance is usually pretty far down the line of reasons as to why I don't like plain "bool". I suspect that the performance isn't particularly relevant most of the time, at least not nowadays.

- Casey
cmuratori
I like to make sure that I know the sizes of everything that I put in my structures.


Could you elaborate on the reason(s) for this?
cmuratori
Performance is usually pretty far down the line of reasons as to why I don't like plain "bool". I suspect that the performance isn't particularly relevant most of the time, at least not nowadays.


If I haven't missed anything performance was the only reason you gave on the stream when you introduced the bool32 type.
Nimbal
cmuratori
I like to make sure that I know the sizes of everything that I put in my structures.


Could you elaborate on the reason(s) for this?


It's so he can add it to the address to get another var or to count an array or if he had a chunk of memory he can easily find stuff in that chunk by doing a sizeof and adding it to the address.
In one episode, he allocated a chunk of memory

blah = VirtualAlloc(1000mb

so he can do

mystruct* one = (mystuct*) blah

and that chunk will store "one".

then he can do more

mystruct2* two = (mystruct2*) (sizeof(mystruct) + blah)

to store "two" in that chunk. This just adds the the size of mystruct to the address of blah to get a new offset in that chunk so we can store mystruct2.
The size of a structure is all of the variable sizes inside that structure. If you are not sure of a size of a variable then it would be hard to do this easy calculation.

Edited by popcorn on
cmuratori
One very important one is that it is not clear how big "bool" is, whereas it is very clear how big "bool32" is, and generally I like to make sure that I know the sizes of everything that I put in my structures.

That also sounds like a good argument for "bool8", subject to the usual disclaimer about putting bools in structs being a bad idea, at least if it's a struct that you have a lot of.

Having said that, now that you mention it, using bitfields of bool32 to store the "bundle of flags" (the one that's ubiquitous in certain types of struct) sounds like a useful piece of documentation to me.
C0D3

blah = VirtualAlloc(1000mb

so he can do

mystruct* one = (mystuct*) blah

and that chunk will store "one".

then he can do more

mystruct2* two = (mystruct2*) (sizeof(mystruct) + blah)

to store "two" in that chunk. This just adds the the size of mystruct to the address of blah to get a new offset in that chunk so we can store mystruct2.
The size of a structure is all of the variable sizes inside that structure. If you are not sure of a size of a variable then it would be hard to do this easy calculation.


That is not the reason for wanting to know the size of structs. The compiler works this out when you use the 'sizeof' operator. You never would want to write whatever you think the size of that struct is instead of sizeof since you had to update that.


But I'd be interested in Casey's reason for wanting to know the sizes before as well.
If somebody missed, Casey talked about why he uses bool32 not bool in previous episodes:
https://forums.handmadehero.org/j...videos/win32-platform/day007.html "Bool datatype idiosyncraries (9:21)"
https://forums.handmadehero.org/j...videos/win32-platform/day009.html "Sometimes you use 'bool' and sometimes 'bool32' (1:48:48)"

As for knowing sizes I would assume it's more about alignment in structures or array of structures. If you do this:
1
2
3
4
5
6
struct S
{
  int x;
  bool y;
  int z;
};

and you are not paying attention to bool size, then it could be that sizeof(bool) is 1 and then sizeof(S) is 12, not 9. If you are not careful with this, you will be wasting a lot of space.

That's why you want to specify exact sizes, so you know what is happening. If you put bool32 in this struct, then you know exactly what is happening.
mmozeiko
If somebody missed, Casey talked about why he uses bool32 not bool in previous episodes:
https://forums.handmadehero.org/j...videos/win32-platform/day007.html "Bool datatype idiosyncraries (9:21)"
https://forums.handmadehero.org/j...videos/win32-platform/day009.html "Sometimes you use 'bool' and sometimes 'bool32' (1:48:48)"

As for knowing sizes I would assume it's more about alignment in structures or array of structures. If you do this:
1
2
3
4
5
6
struct S
{
  int x;
  bool y;
  int z;
};

and you are not paying attention to bool size, then it could be that sizeof(bool) is 1 and then sizeof(S) is 12, not 9. If you are not careful with this, you will be wasting a lot of space.

That's why you want to specify exact sizes, so you know what is happening. If you put bool32 in this struct, then you know exactly what is happening.


Ah that makes sense. I guess you can't have just one bit in the memory, it has to be at least a size of a char 8 bits (2 bytes) or 32bits as he does it.

Edited by popcorn on
mmozeiko
If you are not careful with this, you will be wasting a lot of space.

Waste is important, but it's not the only issue. There are situations where you'd like to guarantee that a bunch of fields which are not at the start of a struct still fall in the same cache line.

Like you said, it's about knowing exactly what is happening.
Yes, of course. Compiling code is easy (compilers are smart). Reading code is not so. That means most of the time good code is needed so it is easier to read and understand what is happening and how it is happening.