I\'m reading Agner Fog\'s \"Optimizing software in C++\" (specific to x86 processors for Intel, AMD and VIA) and it states on page 34
Boolean variabl
I think this is not the case.
First of all, this reasoning is completely unacceptable:
The reason why the compiler doesn't make such an assumption is that the variables might have other values if they are uninitialized or come from unknown sources.
Let's check some code (compiled with clang 6, but GCC 7 and MSVC 2017 produces similar code).
Boolean or:
bool fn(bool a, bool b) {
return a||b;
}
0000000000000000 :
0: 40 08 f7 or dil,sil
3: 40 88 f8 mov al,dil
6: c3 ret
As can be seen, no 0/1 check here, simple or
.
Convert bool to int:
int fn(bool a) {
return a;
}
0000000000000000 :
0: 40 0f b6 c7 movzx eax,dil
4: c3 ret
Again, no check, simple move.
Convert char to bool:
bool fn(char a) {
return a;
}
0000000000000000 :
0: 40 84 ff test dil,dil
3: 0f 95 c0 setne al
6: c3 ret
Here, char is checked whether it is 0, or not, and bool value set to 0 or 1 accordingly.
So I think it is safe to say that the compiler uses bool in a way so it always contains a 0/1. It never checks its validity.
About efficiency: I think bool is optimal. The only case I can imagine, where this approach is not optimal is char->bool conversion. That operation could be a simple mov, if bool value wouldn't be restricted to 0/1. For all other operations, the current approach is equally good, or better.
EDIT: Peter Cordes mentioned ABI. Here's the relevant text from the System V ABI for AMD64 (the text for i386 is similar):
Booleans, when stored in a memory object, are stored as single byte objects the value of which is always 0 (false) or 1 (true). When stored in integer registers (except for passing as arguments), all 8 bytes of the register are significant; any nonzero value is considered true
So for platforms which follow SysV ABI, we can be sure that a bool
has a 0/1 value.
I searched for ABI document for MSVC, but unfortunately I didn't find anything about bool
.