tags:

views:

834

answers:

4

In C++, I'm wondering why the bool type is 8 bits long (on my system), where only one bit is enough to hold the boolean value ?

I used to believe it was for performance reasons, but then on a 32 bits or 64 bits machine, where registers are 32 or 64 bits wide, what's the performance advantage ?

Or is it just one of these 'historical' reasons ?

+54  A: 

Because every C++ data type must be addressable.

How would you create a pointer to a single bit? You can't. But you can create a pointer to a byte. So a boolean in C++ is typically byte-sized. (It may be larger as well. That's up to the implementation. The main thing is that it must be addressable, so no C++ datatype can be smaller than a byte)

jalf
"byte" addressing is an architectural choice (hw level): one could very well design a system with a different "unit of addressing". For common processors, addressing a "byte" anyhow ends-up fetching more than a "byte" from external memory: this is due to efficiency reasons.
jldupont
Yes, it's a hardware choice, and if the hardware allows for it, the size of a bool could change. But the OP asked why a bool is 8 bits wide, and on systems where that is the case, it is generally because the CPU is only able to address 8-bit bytes.
jalf
On many systems a bool is the same size as an int by default, as it is much more efficient to fetch the native word size from memory. And you don't have to do shifting to get to the byte of interest. But like you said, this is an implementation detail, and can often be set using compiler switches.
Brian Neal
@jldupont: There are a few systems where pointer addresses are finer grained than bytes (I've programmed on the old TI TMS34010/20 before, which uses bit-wise pointers), but they are EXCEEDINGLY rare.
Michael Kohne
Because it doesn't matter. The OP didn't ask about those EXCEEDINGLY rare machines. I downvoted you because as detailed as your answer was, it left out the one *true* reason: That C++ requires that every object is addressable. And rather than craft special rules to allow sub-byte datatypes on the EXCEEDINGLY rare systems where it is possible, they simplified it by saying that the fundamental addressing unit in C++ is the byte (where the size of a byte is implementation-defined). And a char is 1 byte, so smaller datatypes aren't possible
jalf
I don't need a trip down memory lane. I know full well that some machines allow bit addressing. I'm not saying that's impossible or implausible. Just that it *doesn't matter to the OP's question*.
jalf
@jalf, all: thanks to all for the very good discussion. I always enjoy these!. Good day! (BTW, I have up-voted you ;-)
jldupont
same here :) (15 chars padding)
jalf
if this is true, why char data type is 1 byte ( 256 characters can store in 8 bit ( and no additional space for storing memory address ) ) ???
Michel Kogan
Not sure what you mean. Every object must be addressable, that is, it must be possible to retrieve the address of an object. The object doesn't have to store its own address. A char is typically 8 bits wide, enough to store any of 256 characters, but each char also has an address defined by where in memory it is located. That is why you can create a pointer to a char.
jalf
@jalf : what about int data type ? size of int types( in my GCC compiler ) is 4 bytes and a Unsigned int can stores 2**32 number ( 0 to 4294967295 ) ... so there is no additional byte for storing memory address ... why bool data type have additional bits for storing memory address but int or char NOT ?
Michel Kogan
Bool doesn't have additional bits for storing the memory address. But because a memory address only points to a byte, not to an individual bit, every data type must take up at least one byte. If a bool was stored in the third bit of a byte somewhere, we would have no way to create a pointer to it. But if it takes up the entire byte, we can create a pointer to that.
jalf
If I may contribute a dodgy analogy: there are eight floors in my building, but the Post Office doesn't acknowledge that they are different addresses. So if I want an address all to myself, then I have to rent the whole building, even though I actually fit on one floor. I'm not using the other seven floors to "store an address", I'm just forced to waste them because of the Post Office rule that addresses refer to buildings, not floors. C++ objects must have an address to themselves - no post rooms to sort the mail after delivery ;-)
Steve Jessop
+1 for dodgy analogies ;)
jalf
@Steve Jessop and @jalf thanks to both for great explanation ... impressive ... ( BTW +1 to answer and comments )
Michel Kogan
+12  A: 

Memory is byte addressable. You cannot address a single bit, without shifting or masking the byte read from memory. I would imagine this is a very large reason.

Stephen Roantree
+7  A: 

A boolean type normally follows the smallest unit of addressable memory of the target machine (i.e. usually the 8bits byte).

Access to memory is always in "chunks" (multiple of words, this is for efficiency at the hardware level, bus transactions): a boolean bit cannot be addressed "alone" in most CPU systems. Of course, once the data is contained in a register, there are often specialized instructions to manipulate bits independently.

For this reason, it is quite common to use techniques of "bit packing" in order to increase efficiency in using "boolean" base data types. A technique such as enum (in C) with power of 2 coding is a good example. The same sort of trick is found in most languages.

Updated: Thanks to a excellent discussion, it was brought to my attention that sizeof(char)==1 by definition in C++. Hence, addressing of a "boolean" data type is pretty tied to the smallest unit of addressable memory (reinforces my point).

jldupont
For all the comments you left about this, it's impressive that you left out the most important part of the answer: A `bool` type follows the smallest unit of allocatable memory **because C++ requires that it must be possible to create pointers to it**. Without that requirement, a `bool` could conceivably have been represented as a single bit even on current byte-addressable machines.
jalf
hmmm... I could craft a CPU architecture where a bit could be addressable... I could even write a compiler etc. for it. I could have a special region of memory (or whatever) that would be "bit addressable". It is not by any stretch of the imagination impossible.
jldupont
Yes, and on that system, a bool could be made to be a single bit. But the OP didn't ask "why is a bool 8 bits wide on jlduponts hypothetical CPU". He asked about current, common, everyday CPUs, and on those, it is because they are byte-addressable.
jalf
I didn't see "everyday CPU" in OP's question...
jldupont
sizeof(char)==1 per definition in C++, so what your hardware can or can not do is not relevant. You can't have sizeof(bool) < sizeof(char). BTW C++ is defined in such a way that you can have "fat" pointer to address some subunit of what the hardware can address if it isn't convenient to have char the smallest hardware addressable unit. This has been used at least in some C compilers for old word addressable architectures.
AProgrammer
@AProgrammer: `sizeof(char)==1 definition` : that's the best counter-argument to my argumentation. Thanks!
jldupont
@jldupont: He did mention 32/64-bit systems. Apart from that, I just saw nothing to indicate that he was asking "why is it a natural law that bool must be 8 bits on **every** conceivable CPU". I read it as "why is it 8 bits on the systems where it *is* 8 bits", which at least makes sense. And with the edit, I just gave you an upvote. :) I just felt most of the rest of the post was missing the point.
jalf
Hmm... I suppose there's no reason you couldn't have a pointer to a bit; the pointer type would need to be 3 bits wider than the usual pointer types, is all. Now to find a computer that can handle 35-bit (or 67-bit) words natively....
Jeremy Friesner
@Jeremy: IBM 704 has 36bits words. Many DSP processors have "strange" word length too. I can bet you that many custom processors used in security devices use that trick too. Once, long ago, I have designed a CPU with some pretty strange (but today's standards) properties.
jldupont
+2  A: 

The answers about 8-bits being the smallest amount of memory that is addressable are correct. However, some languages can use 1-bit for booleans, in a way. I seem to remember Pascal implementing sets as bit strings. That is, for the following set:

{1, 2, 5, 7}

You might have this in memory:

01100101

You can, of course, do something similar in C / C++ if you want. (If you're keeping track of a bunch of booleans, it could make sense, but it really depends on the situation.)

Benjamin Oakes
In fact, C++ does this with the specialised container vector<bool> - it is commonly seen as a disaster.
anon
C++ also does this with "bit fields," inherited from C. When declaring a member variable of a struct/class, you can declare the number of bits used to store the value (e.g., "unsigned short field : 3").
@Neil : why is it commonly seen as a disaster ? Is it a performance problem ?
Jérôme
@Jerome: It's because, since a bit is not addressable, it can't behave the way as a regular `vector`. It isn't actually an STL-type container, because there are constraints on the behavior. What's worse is that it causes problems with somebody having `bool`s and wanting to make a `vector` of them. It is surprising behavior, and that's not what you want in a language.
David Thornley
Well, there are possible performance problems, but basically it will no longer work like a C++ STL container (particularly with iterators) precisely because bits are not addressable.
anon
@jldupont - it's sufficient to make a point like this once. And C++ makes no guarantee that bits are addressable (rather the reverse), no matter what the hardware is capable of.
anon
@Neil: noted. Thanks for the gentle reminder. CHeers.
jldupont