For the most part, it's a more accurate representation of what's actually happening on the CPU.
As a local, a bool is going to either be in a register (in which case the size is irrelevant), or on the stack, in which case it's bound by stack alignment and is going to take up more than a byte anyway.
In a struct, the alignment is probably going to cost more than a byte as well:
| struct Foo {
s64 x; // Forces alignment to 8
bool b;
};
// sizeof(Foo) == 16
|
Using a type that is explicitly 32 bits makes that cost clear.
A more subtle reason is that the C++ bool type is defined to only hold the values 0 or 1. Which means that when you assign to a bool, the compiler may have to emit code to enforce this. Consider bitflags:
1
2
3
4
5
6
7
8
9
10
11
12 | enum {
//...
Flag_Baz = 1 << 3,
//...
};
// Here, compiler must do a compare against zero and then set the bool, rather than a direct assignment.
// baz_set will be either 0 or 1
bool baz_set = flags & Flag_Baz;
// Here, we can just assign the value directly:
// baz_set will be either 0 or Flag_Baz
b32 baz_set = flags & Flag_Baz;
|
Finally, if you're concerned about the memory cost, you shouldn't be using *either* b32 or bool. The standard bool still uses 8 bits to store 1 bit of data, which is an *awful* use of space. Instead we use implicit relationships to avoid storing boolean values, and bitflags to compress them together when we have to.