Types of char in C++ (confused by C++ primer explanation)

Viewed 148

The book states the following:

Unlike the other integer types, there are three distinct basic character types: char, signed char, and unsigned char. In particular, char is not the same type as signed char. Although there are three character types, there are only two representations: signed and unsigned. The (plain) char type uses one of these representations. Which of the other two character representations is equivalent to char depends on the compiler.

This description is confusing. It says that char is not the same as signed char, but then says it uses "one of the two representations: signed and unsigned."

It also states that there are only "2 representations," but three actual types. What is this saying exactly?

3 Answers

This is trying to communicate that compilers are free to decide which interpretation they take, either signed or unsigned, and as a programmer you must understand that it might not be what you expect. If you're used to it being signed, another compiler might be unsigned, and your code might break because of that assumption.

As such, if you need signed or unsigned, use the appropriate keyword, or better, use something like uint8_t to make it abundantly clear what you want.

int and others are only unsigned if so specified. char is a bit of a loose cannon here.

A representation determines how the bits in a memory region should be interpreted if we know it contains objects of a certain type.

For instance: on a platform where int and float are both 4 bytes long, a compiler would interpret the bits in a 4 byte word differently if it was declared to hold a float than if it were declared to hold an int. Both int and float are distinct types that impose some value representation (and interpretation) of bits. But those representations don't have to belong just to those types. If on our platform a long int was also 4 bytes long, then it would almost certainly have the same representation as an int, even though they are distinct types.

This is similar to the case the book is describing. There are two types, singed char and unsgined char. Each imposes its own representation (and interpretation) of the bits in its storage.

And next to those two types, there is another, third type, which is named plainly char and is not the same type as the other two (just like long int is not the same type as an int). However, it's the same size as both of the others, and has the same representation as one of them (which exactly is implementation defined).

If an integer type is signed it means that it holds negative and positive values and the value 0.

If an integer type is unsigned it means that it holds positive values and the value 0. It cannot hold negative values.

Some types have "more names". E.g. long, long int and signed long int are all names for the same type.

Let's see what is the case with most of the integer types. E.g. int and signed int are the exact same type. These are two names for the same type. This type is signed (holds negative and positive values and the value 0). unsigned int is a different type, it is unsigned, i.e. it only holds positive values and the value zero. This pattern repeats for all integer types (short, long etc)

The exception to this is char: char, unsigned char and signed char are 3 different types. signed char is signed, unsigned char is unsigned and char well it can be either signed or unsigned depending on the compiler and platform.

Now what does it mean that two types are different? For beginners it really doesn't make much of an impact. This fact comes more into play in function overloading and meta programming.

Related