39

Size of char, signed char and unsigned char is defined to be 1 byte, by the C++ Standard itself. I'm wondering why it didn't define the sizeof(bool) also?

C++03 Standard $5.3.3/1 says,

sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1; the result of sizeof applied to any other fundamental type (3.9.1) is implementation-defined. [Note: in particular,sizeof(bool) and sizeof(wchar_t) are implementation-defined.69)

I understand the rationale that sizeof(bool) cannot be less than one byte. But is there any rationale why it should be greater than 1 byte either? I'm not saying that implementations define it to be greater than 1, but the Standard left it to be defined by implementation as if it may be greater than 1.

If there is no reason sizeof(bool) to be greater than 1, then I don't understand why the Standard didn't define it as just 1 byte, as it has defined sizeof(char), and it's all variants.

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • `sizeof(char)` is specified to be one, but is it specified to be one byte ? I don't think the exact size is precised, in case an architecture comes out that stores bits by 16 instead of 8. – Matthieu M. Feb 21 '11 at 15:12
  • 13
    @Matthieu: "one byte" is also defined to be the same as a char ;-). If an architecture stores bits by 16, then there are 16 bits in a byte as far as C++ is concerned on that platform. Any belief you may have that "byte" means "octet" must be left at the door... – Steve Jessop Feb 21 '11 at 15:13
  • 8
    @Matthieu: the **unit** of sizeof is *byte*. But byte doesn't necessarily mean 8 bits! – Nawaz Feb 21 '11 at 15:13
  • @Steve, @Nawaz: Ah thanks, didn't remember the distinction :) – Matthieu M. Feb 21 '11 at 15:15
  • 2
    @MatthieuM.: `CHAR_BIT`, defined in `` or ``, specifes the number of bits in a byte. – Keith Thompson Jan 15 '14 at 19:54
  • Possible duplicate of [Why is a char and a bool the same size in c++?](https://stackoverflow.com/questions/266870/why-is-a-char-and-a-bool-the-same-size-in-c) – underscore_d May 23 '17 at 20:38

4 Answers4

31

The other likely size for it is that of int, being the "efficient" integer type for the platform.

On architectures where it makes any difference whether the implementation chooses 1 or sizeof(int) there could be a trade-off between size (but if you're happy to waste 7 bits per bool, why shouldn't you be happy to waste 31? Use bitfields when size matters) vs. performance (but when is storing and loading bool values going to be a genuine performance issue? Use int explicitly when speed matters). So implementation flexibility wins - if for some reason 1 would be atrocious in terms of performance or code size, it can avoid it.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
28

As @MSalters pointed out, some platforms work more efficiently with larger data items.

Many "RISC" CPUs (e.g., MIPS, PowerPC, early versions of the Alpha) have/had a considerably more difficult time working with data smaller than one word, so they do the same. IIRC, with at least some compilers on the Alpha a bool actually occupied 64 bits.

gcc for PowerPC Macs defaulted to using 4 bytes for a bool, but had a switch to change that to one byte if you wanted to.

Even for the x86, there's some advantage to using a 32-bit data item. gcc for the x86 has (or at least used to have -- I haven't looked recently at all) a define in one of its configuration files for BOOL_TYPE_SIZE (going from memory, so I could have that name a little wrong) that you could set to 1 or 4, and then re-compile the compiler to get a bool of that size.

As for the reason behind this, I'd say it's a simple reflection of a basic philosophy of C and C++: leave as much room for the implementation to optimize/customize its behavior as reasonable. Require specific behavior only when/if there's an obvious, tangible benefit, and unlikely to be any major liability, especially if the change would make it substantially more difficult to support C++ on some particular platform (though, of course, if the platform is sufficiently obscure, it might get ignored).

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • If memory serves, the reason behind it on Mac OS X was that cross-platform OS code had assumed `bool` to be compatible with atomic operations, but PowerPC required higher alignment. There was no time to add the missing `typedef` and no other way to define an interface boundary between differing definitions of `bool`. The older Mac OS (including presumably its GCC port) had 1-byte `bool`, and the switch probably provided compatibility to such code at the expense of no longer being able to use many BSD system calls. Programmers then had to wean from the switch by defining their own `bool`. – Potatoswatter Jan 05 '14 at 04:59
20

Many platforms cannot effectively load values smaller than 32 bits. They have to load 32 bits, and use a shift-and-mask operation to extract 8 bits. You wouldn't want this for single bools, but it's OK for strings.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • Many platforms? Such as? If such platforms exist, then do they really define `sizeof(bool)` greater than 1? – Nawaz Feb 21 '11 at 15:07
  • 6
    ARM, for one, although it's really the `STRB` (Store Byte) instruction which is funny. _"STRB repeats the bottom 8 bits of the source register four times across the data bus. The external memory system should activate the appropriate byte subsystem to store the data."_ – MSalters Feb 21 '11 at 15:12
  • 4
    STRB isn't repeating the same byte over four bus cycles, it repeats it four times over one bus cycle, and the memory controller can slurp the data off any byte lane. It doesn't take any longer than storing a word with STR. – rsaxvc Mar 16 '14 at 05:18
  • please consider your answer is vague (Even your answer is correct), users have to read all other answers to find out what did you say about this question. – Hadi Rasekh Aug 31 '15 at 11:27
1

The operation resulted in 'sizeof' is MADUs (minimal addresible unit), not bytes. So family processors C54 *. C55 * Texas Instuments, the expression 1 MADU = 2 bytes.

For this platform sizeof (bool) = sizeof (char) = 1 MADUs = 2 bytes. This does not violate the C + + standard, but clarifies the situation.

  • 4
    No, the value yielded by `sizeof` is in bytes. The C++ standard defines the word "byte" differently than the way it's commonly used. If the minimum addressible unit is 16 bits, then a byte (as defined by both C and C++) is 16 bits for that platform. `sizeof (char) == 1` by definition; if `sizeof (char)` yields 2, your compiler is non-conforming. – Keith Thompson Jan 15 '14 at 19:56
  • 1
    Reference: ISO C++ 2011 standard, 5.3.3 [expr.sizeof]: "The **`sizeof`** operator yields the number of bytes in the object representation of its operand." – Keith Thompson Jan 15 '14 at 20:04
  • It's worth emphasising what @KeithThompson says here: the C (and C++) standard define `byte` to be `sizeof(char)`, and not the other way round. If you're only a platform where `sizeof(char)` is not 8 bits you will have a very bad time until you realise this. – David Given Jan 13 '16 at 23:46
  • I guess you could find out the number of bytes in the usual sense using `CHAR_BIT/8`, however I could not find a rule prescribing that `CHAR_BIT` must be a multiple of 8. Considering the answers above, it very, very likely is on any platfrom, though. – Quirin F. Schroll Feb 24 '22 at 13:17