I'm reading The C++ Programming Language and in it Stroustrup states that the int value of a char can range from 0 to 255 or -127 to 127, depending on implementation. Is this correct? It seems like it should be from -128 to 127. If not, why are their only 255 possible values in the second implementation possibility, not 256.
You're stuck in two's complement thinking - The C++ standard does not define the representation used for negative numbers!
If your computer (god forbid) uses ones's complement to represent negative numbers, you have a range of -127 to + 127 in an 8-bit byte. On the upside, you have two different possible representations for zero...
However, in the real world, you're unlikely to meet a one's complement computer.
From reading that it seems it can be any of those, depending on implementation.
Thanks Roddy and Esteban Brenes for the helpful replies.
This is my current understanding:
There are three possibilities. If the values are represented as unsigned, a char will range from 0 to 255. If the values are represented as signed in two's complement, a char will range from -128 to 127. Finally, if the values are represented as signed in one's complement, a char will range from -127 to 127. This final possibility suggests that there would only be 255 possible values in contrast to the 256 possible values for the first two implementations, but this fails to take into account the negative zero in one's complement representations.
It's wrong to think that an unsigned char ranges from 0 to 255. that's only its minimal range. a char must have at least 8 bits, and signed char, unsigned char and char itself can have indeed more that just 8 bits. so then that means that unsigned char could go beyond 255. though admittedly, i haven't got an implementation where it had more than 8 bits, it theoretically is possible. that's specified in the c89 standard (on which c++03 bases), documenting file limits.h (CHAR_BIT, UCHAR_MAX, CHAR_MAX).
Because the standard doesn't say anything about the char type, "char" can be:
"unsigned char" (0-255) on some compilers (example: TexasInstruments compiler for their ARM processors - OMAP series)
"signed char" (-128-127) on most compilers (gcc, MSVC ...)
To make sure you always have a well defined range you should use "signed char" or "unsigned char".