Why do objects of the types bool and _Bool in C and bool in C++ can store only the values of 0 or 1 if they occupy 1 byte in memory which could hold 256 values?
If bool
can store the whole value range of a char
then why don't just use char
?
Of course, Their purpose is to represent only the values of 0 and 1 or true and false, but which unit or macro decides that it only can store 0 or 1?
The compiler will handle the conversion when you assign a value to a bool variable. If it's truthy then the variable will contains true
. That behavior was defined in the C and C++ standards. That means bool a; a = 25;
is completely valid and not "an inappropriate assignment" as you though. After that a
will always contain true/1. You can never set a bool to anything other than 0 and 1 via normal variable assignment
There's no problem using a char or an int as bool like how it was before modern C and C++, but by limiting the value range it also allows the compiler to do a lot of optimizations. For example bool x = !y;
will be done by a simple XOR instruction, which will not work if y contains any values other than 0 and 1. If y is a normal integer type then you'll need to normalize y to 0 and 1 first. See demo
As a matter of fact, not all bits in the representation have to involve in value calculation, and not all bit patterns have to be valid. C and C++ allow types to contain padding bits and trap representations, so a 32-bit type may have only 30 value bits, or be able to store only 232-4 different values. This is not to say that bool definitely contains padding bits, just a proof that you are permitted to have a type narrower than the possible range
The only exception we are aware of is _Bool
(as observed by Joseph Myers wrt GCC). It seems one could either (a) take non {0,1} values to be trap representations in the current sense, or (b) regard operations on non {0,1} values of that type as giving an unspecified value. The latter would bound possible misbehaviour, which would be good for programmers; the only possible downside we are aware of is that it could limit compilation via computed branch tables indexed by unchecked _Bool
values.
N2091: Clarifying Trap Representations (Draft Defect Report or Proposal for C2x)
However some implementations do consider them trap representations
In fact, as implemented by GCC and Clang, the _Bool type has two values and 254 trap representations.
Trap representations and padding bits - Pascal Cuoq
And what would happen if the value of a boolean type is accidentally modified in memory to a greater value?
If you manipulate the value of the bool to another value directly via a pointer then in C++ undefined behavior will happen
6.9.1 Fundamental types
Values of type bool are either true or false. 50 [Note: There are no signed, unsigned, short, or long bool types or values. — end note] Values of type bool participate in integral promotions (7.6).
50) Using a bool value in ways described by this International Standard as “undefined”, such as by examining the value of an uninitialized automatic object, might cause it to behave as if it is neither true nor false.
C++17
I couldn't find the reference in C99 but it will be undefined behavior if the value you set is a trap representation
6.2.6 Representations of types
Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined. If such a representation is produced by a side effect that modifies all or any part of the object by an lvalue expression that does not have character type, the behavior is undefined.41) Such a representation is called a trap representation.
There are already many questions regarding that "weird" behavior